new pasto-o-matic for time
[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)) {
389 gtk_tree_view_set_headers_clickable(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{
406 guint val = 20;
606309a4 407
42fcbb71 408 insert_viewer((GtkWidget*)menuitem, (lttvwindow_viewer_constructor)user_data);
37d0eca6 409 // selected_hook(&val);
561eba2a 410}
411
561eba2a 412
413/* internal functions */
2d262115 414void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor)
561eba2a 415{
b052368a 416 GtkWidget * viewer_container;
501e4e70 417 MainWindow * mw_data = get_window_data_struct(widget);
6ced96ef 418 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
f9334f6f 419 GtkWidget * viewer;
49bf71b5 420 LttvTracesetSelector * s;
202f6c8f 421 TimeInterval * time_interval;
6ced96ef 422 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
423 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
424 Tab *tab;
425
426 if(!page) {
427 tab = create_new_tab(widget, NULL);
428 } else {
429 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
47cd8a09 430 }
431
b052368a 432 viewer_container = tab->viewer_container;
561eba2a 433
501e4e70 434 s = construct_traceset_selector(tab->traceset_info->traceset);
d47b33d2 435 viewer = (GtkWidget*)constructor(tab);
f9334f6f 436 if(viewer)
f0d936c0 437 {
b052368a 438 //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer);
439
440 gtk_box_pack_end(GTK_BOX(viewer_container),
441 viewer,
442 TRUE,
443 TRUE,
444 0);
445
f37a2002 446 /* We want to connect the viewer_grab_focus to EVERY
447 * child of this widget. The little trick is to get each child
448 * of each GTK_CONTAINER, even subchildren.
449 */
0f9d55ef 450 connect_focus_recursive(viewer, viewer);
f0d936c0 451 }
561eba2a 452}
453
313bd6fc 454/**
455 * Function to set/update traceset for the viewers
456 * @param tab viewer's tab
457 * @param traceset traceset of the main window.
458 * return value :
459 * 0 : traceset updated
460 * 1 : no traceset hooks to update; not an error.
461 */
462
463int SetTraceset(Tab * tab, LttvTraceset *traceset)
464{
b052368a 465 LttvTracesetContext *tsc =
466 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
467 TimeInterval time_span = tsc->time_span;
e800cf84 468 TimeWindow new_time_window;
469 LttTime new_current_time;
1ba187d3 470
471 /* Set the tab's time window and current time if
472 * out of bounds */
473 if(ltt_time_compare(tab->time_window.start_time, time_span.start_time) < 0
474 || ltt_time_compare( ltt_time_add(tab->time_window.start_time,
475 tab->time_window.time_width),
476 time_span.end_time) > 0) {
e800cf84 477 new_time_window.start_time = time_span.start_time;
478
479 new_current_time = time_span.start_time;
1ba187d3 480
481 LttTime tmp_time;
482
483 if(DEFAULT_TIME_WIDTH_S < time_span.end_time.tv_sec)
484 tmp_time.tv_sec = DEFAULT_TIME_WIDTH_S;
485 else
486 tmp_time.tv_sec = time_span.end_time.tv_sec;
487 tmp_time.tv_nsec = 0;
e800cf84 488 new_time_window.time_width = tmp_time ;
1ba187d3 489 }
e800cf84 490 time_change_manager(tab, new_time_window);
491 current_time_change_manager(tab, new_current_time);
492
493#if 0
1ba187d3 494 /* Set scrollbar */
b052368a 495 GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(tab->scrollbar));
0c5dbe3b 496 LttTime upper = ltt_time_sub(time_span.end_time, time_span.start_time);
b052368a 497
498 g_object_set(G_OBJECT(adjustment),
499 "lower",
0c5dbe3b 500 0.0, /* lower */
b052368a 501 "upper",
0c5dbe3b 502 ltt_time_to_double(upper)
b052368a 503 * NANOSECONDS_PER_SECOND, /* upper */
504 "step_increment",
505 ltt_time_to_double(tab->time_window.time_width)
506 / SCROLL_STEP_PER_PAGE
507 * NANOSECONDS_PER_SECOND, /* step increment */
508 "page_increment",
509 ltt_time_to_double(tab->time_window.time_width)
510 * NANOSECONDS_PER_SECOND, /* page increment */
511 "page_size",
512 ltt_time_to_double(tab->time_window.time_width)
513 * NANOSECONDS_PER_SECOND, /* page size */
514 NULL);
515 gtk_adjustment_changed(adjustment);
516
517 g_object_set(G_OBJECT(adjustment),
518 "value",
b9a010a2 519 ltt_time_to_double(
520 ltt_time_sub(tab->time_window.start_time, time_span.start_time))
521 * NANOSECONDS_PER_SECOND, /* value */
b052368a 522 NULL);
523 gtk_adjustment_value_changed(adjustment);
1ba187d3 524
e800cf84 525 /* set the time bar. The value callbacks will change their nsec themself */
526 /* start seconds */
527 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry1),
528 (double)time_span.start_time.tv_sec,
529 (double)time_span.end_time.tv_sec);
530
531 /* end seconds */
532 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry3),
533 (double)time_span.start_time.tv_sec,
534 (double)time_span.end_time.tv_sec);
535
536 /* current seconds */
537 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry5),
538 (double)time_span.start_time.tv_sec,
539 (double)time_span.end_time.tv_sec);
540#endif //0
541
1ba187d3 542 /* Finally, call the update hooks of the viewers */
543 LttvHooks * tmp;
544 LttvAttributeValue value;
545 gint retval = 0;
546
547
548 g_assert( lttv_iattribute_find_by_path(tab->attributes,
549 "hooks/updatetraceset", LTTV_POINTER, &value));
550
551 tmp = (LttvHooks*)*(value.v_pointer);
552 if(tmp == NULL) retval = 1;
553 else lttv_hooks_call(tmp,traceset);
554
555
b052368a 556 return retval;
313bd6fc 557}
558
559/**
560 * Function to set/update filter for the viewers
561 * @param tab viewer's tab
562 * @param filter filter of the main window.
563 * return value :
564 * -1 : error
565 * 0 : filters updated
566 * 1 : no filter hooks to update; not an error.
567 */
568
569int SetFilter(Tab * tab, gpointer filter)
570{
571 LttvHooks * tmp;
572 LttvAttributeValue value;
573
574 g_assert(lttv_iattribute_find_by_path(tab->attributes,
575 "hooks/updatefilter", LTTV_POINTER, &value));
576
577 tmp = (LttvHooks*)*(value.v_pointer);
578
579 if(tmp == NULL) return 1;
580 lttv_hooks_call(tmp,filter);
581
582 return 0;
583}
584
585
586
587/**
588 * Function to redraw each viewer belonging to the current tab
589 * @param tab viewer's tab
590 */
591
592void update_traceset(Tab *tab)
593{
594 LttvAttributeValue value;
595 LttvHooks * tmp;
596 g_assert(lttv_iattribute_find_by_path(tab->attributes,
597 "hooks/updatetraceset", LTTV_POINTER, &value));
598 tmp = (LttvHooks*)*(value.v_pointer);
599 if(tmp == NULL) return;
600 lttv_hooks_call(tmp, NULL);
601}
602
abe346a3 603
604/* get_label function is used to get user input, it displays an input
605 * box, which allows user to input a string
606 */
607
561eba2a 608void get_label_string (GtkWidget * text, gchar * label)
609{
610 GtkEntry * entry = (GtkEntry*)text;
611 if(strlen(gtk_entry_get_text(entry))!=0)
612 strcpy(label,gtk_entry_get_text(entry));
613}
614
eb38aea5 615gboolean get_label(MainWindow * mw, gchar * str, gchar* dialogue_title, gchar * label_str)
561eba2a 616{
617 GtkWidget * dialogue;
618 GtkWidget * text;
619 GtkWidget * label;
620 gint id;
621
5723fa24 622 dialogue = gtk_dialog_new_with_buttons(dialogue_title,NULL,
561eba2a 623 GTK_DIALOG_MODAL,
624 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
625 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
626 NULL);
627
6b1d3120 628 label = gtk_label_new(label_str);
561eba2a 629 gtk_widget_show(label);
630
631 text = gtk_entry_new();
632 gtk_widget_show(text);
633
634 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), label,TRUE, TRUE,0);
635 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), text,FALSE, FALSE,0);
636
637 id = gtk_dialog_run(GTK_DIALOG(dialogue));
638 switch(id){
639 case GTK_RESPONSE_ACCEPT:
640 get_label_string(text,str);
641 gtk_widget_destroy(dialogue);
642 break;
643 case GTK_RESPONSE_REJECT:
644 default:
645 gtk_widget_destroy(dialogue);
eb38aea5 646 return FALSE;
561eba2a 647 }
eb38aea5 648 return TRUE;
561eba2a 649}
650
abe346a3 651
652/* get_window_data_struct function is actually a lookup function,
653 * given a widget which is in the tree of the main window, it will
654 * return the MainWindow data structure associated with main window
655 */
656
bca3b81f 657MainWindow * get_window_data_struct(GtkWidget * widget)
561eba2a 658{
659 GtkWidget * mw;
bca3b81f 660 MainWindow * mw_data;
561eba2a 661
662 mw = lookup_widget(widget, "MWindow");
663 if(mw == NULL){
664 g_printf("Main window does not exist\n");
2d262115 665 return NULL;
561eba2a 666 }
667
2d262115 668 mw_data = (MainWindow *) g_object_get_data(G_OBJECT(mw),"main_window_data");
68b48a45 669 if(mw_data == NULL){
561eba2a 670 g_printf("Main window data does not exist\n");
2d262115 671 return NULL;
561eba2a 672 }
68b48a45 673 return mw_data;
561eba2a 674}
675
abe346a3 676
677/* create_new_window function, just constructs a new main window
678 */
679
68b48a45 680void create_new_window(GtkWidget* widget, gpointer user_data, gboolean clone)
561eba2a 681{
bca3b81f 682 MainWindow * parent = get_window_data_struct(widget);
561eba2a 683
561eba2a 684 if(clone){
685 g_printf("Clone : use the same traceset\n");
08b1c66e 686 construct_main_window(parent);
561eba2a 687 }else{
688 g_printf("Empty : traceset is set to NULL\n");
08b1c66e 689 construct_main_window(NULL);
561eba2a 690 }
691}
692
0f9d55ef 693/* Get the currently focused viewer.
694 * If no viewer is focused, use the first one.
695 *
696 * If no viewer available, return NULL.
697 */
b052368a 698GtkWidget *viewer_container_focus(GtkWidget *container)
699{
700 GtkWidget *widget;
701
702 widget = (GtkWidget*)g_object_get_data(G_OBJECT(container),
bb574a9c 703 "focused_viewer");
b052368a 704
0f9d55ef 705 if(widget == NULL) {
706 g_debug("no widget focused");
707 GList *children = gtk_container_get_children(GTK_CONTAINER(container));
708
709 if(children != NULL)
710 widget = GTK_WIDGET(children->data);
bb574a9c 711 g_object_set_data(G_OBJECT(container),
712 "focused_viewer",
713 widget);
0f9d55ef 714 }
715
b052368a 716 return widget;
717
718
719}
720
721gint viewer_container_position(GtkWidget *container, GtkWidget *child)
722{
723
724 if(child == NULL) return -1;
725
726 gint pos;
727 GValue value = { 0, };
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]);
862 g_printf("Open a trace set %s\n", dir[0]);
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);
882 if(events_request->before_chunk_traceset != NULL)
883 lttv_hooks_destroy(events_request->before_chunk_traceset);
884 if(events_request->before_chunk_trace != NULL)
885 lttv_hooks_destroy(events_request->before_chunk_trace);
886 if(events_request->before_chunk_tracefile != NULL)
887 lttv_hooks_destroy(events_request->before_chunk_tracefile);
888 if(events_request->event != NULL)
889 lttv_hooks_destroy(events_request->event);
890 if(events_request->event_by_id != NULL)
891 lttv_hooks_by_id_destroy(events_request->event_by_id);
892 if(events_request->after_chunk_tracefile != NULL)
893 lttv_hooks_destroy(events_request->after_chunk_tracefile);
894 if(events_request->after_chunk_trace != NULL)
895 lttv_hooks_destroy(events_request->after_chunk_trace);
896 if(events_request->after_chunk_traceset != NULL)
897 lttv_hooks_destroy(events_request->after_chunk_traceset);
898 if(events_request->before_request != NULL)
899 lttv_hooks_destroy(events_request->before_request);
900 if(events_request->after_request != NULL)
901 lttv_hooks_destroy(events_request->after_request);
902
903 g_free(events_request);
904}
905
906
abe346a3 907
501e4e70 908/* lttvwindow_process_pending_requests
909 *
910 * This internal function gets called by g_idle, taking care of the pending
911 * requests. It is responsible for concatenation of time intervals and position
912 * requests. It does it with the following algorithm organizing process traceset
913 * calls. Here is the detailed description of the way it works :
914 *
915 * - Events Requests Servicing Algorithm
916 *
917 * Data structures necessary :
918 *
919 * List of requests added to context : list_in
920 * List of requests not added to context : list_out
921 *
922 * Initial state :
923 *
924 * list_in : empty
925 * list_out : many events requests
926 *
927 * FIXME : insert rest of algorithm here
928 *
abe346a3 929 */
930
6ea08962 931#define list_out tab->events_requests
a43d67ba 932
501e4e70 933gboolean lttvwindow_process_pending_requests(Tab *tab)
a8c0f09d 934{
935 unsigned max_nb_events;
936 GdkWindow * win;
937 GdkCursor * new;
938 GtkWidget* widget;
a43d67ba 939 LttvTracesetContext *tsc;
501e4e70 940 LttvTracefileContext *tfc;
501e4e70 941 GSList *list_in = NULL;
942 LttTime end_time;
943 guint end_nb_events;
2d262115 944 guint count;
501e4e70 945 LttvTracesetContextPosition *end_position;
a43d67ba 946
b052368a 947 if(tab == NULL) {
948 g_critical("Foreground processing : tab does not exist. Processing removed.");
501e4e70 949 return FALSE;
b052368a 950 }
a43d67ba 951
501e4e70 952 /* There is no events requests pending : we should never have been called! */
6ea08962 953 g_assert(g_slist_length(list_out) != 0);
a43d67ba 954
501e4e70 955 tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
a8c0f09d 956
abe346a3 957 //set the cursor to be X shape, indicating that the computer is busy in doing its job
a0577796 958#if 0
a8c0f09d 959 new = gdk_cursor_new(GDK_X_CURSOR);
2d262115 960 widget = lookup_widget(tab->mw->mwindow, "MToolbar1");
a8c0f09d 961 win = gtk_widget_get_parent_window(widget);
962 gdk_window_set_cursor(win, new);
963 gdk_cursor_unref(new);
964 gdk_window_stick(win);
965 gdk_window_unstick(win);
a0577796 966#endif //0
a43d67ba 967
6ea08962 968 g_debug("SIZE events req len : %d", g_slist_length(list_out));
969
970 /* Preliminary check for no trace in traceset */
971 /* Unregister the routine if empty, empty list_out too */
972 if(lttv_traceset_number(tsc->ts) == 0) {
973
974 /* - For each req in list_out */
975 GSList *iter = list_out;
976
977 while(iter != NULL) {
978
979 gboolean remove = FALSE;
980 gboolean free_data = FALSE;
981 EventsRequest *events_request = (EventsRequest *)iter->data;
982
983 /* - Call end request for req */
984 if(events_request->servicing == TRUE)
985 lttv_hooks_call(events_request->after_request, (gpointer)tsc);
986
987 /* - remove req from list_out */
988 /* Destroy the request */
989 remove = TRUE;
990 free_data = TRUE;
991
992 /* Go to next */
993 if(remove)
994 {
995 GSList *remove_iter = iter;
996
997 iter = g_slist_next(iter);
b052368a 998 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
6ea08962 999 list_out = g_slist_remove_link(list_out, remove_iter);
1000 } else { // not remove
1001 iter = g_slist_next(iter);
1002 }
1003 }
1004 }
501e4e70 1005
b052368a 1006 /* 0.1 Lock Traces */
1007 {
1008 guint iter_trace=0;
1009
1010 for(iter_trace=0;
1011 iter_trace<lttv_traceset_number(tsc->ts);
1012 iter_trace++) {
1013 LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
1014
1015 if(lttvwindowtraces_lock(trace_v) != 0) {
1016 g_critical("Foreground processing : Unable to get trace lock");
1017 return TRUE; /* Cannot get lock, try later */
1018 }
1019 }
1020 }
1021
1022 /* 0.2 Seek tracefiles positions to context position */
1023 lttv_process_traceset_synchronize_tracefiles(tsc);
1024
1025
501e4e70 1026 /* Events processing algorithm implementation */
dd316a11 1027 /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
1028 * instead is to leave the control to GTK and take it back.
1029 */
501e4e70 1030 /* A. Servicing loop */
dd316a11 1031 //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
3bafb436 1032 if((g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
1033 /* Servicing */
1034 /* 1. If list_in is empty (need a seek) */
1035 if( g_slist_length(list_in) == 0 ) {
501e4e70 1036
3bafb436 1037 /* list in is empty, need a seek */
dd316a11 1038 {
3bafb436 1039 /* 1.1 Add requests to list_in */
1040 GSList *ltime = NULL;
1041 GSList *lpos = NULL;
1042 GSList *iter = NULL;
501e4e70 1043
3bafb436 1044 /* 1.1.1 Find all time requests with the lowest start time in list_out
1045 * (ltime)
1046 */
1047 if(g_slist_length(list_out) > 0)
1048 ltime = g_slist_append(ltime, g_slist_nth_data(list_out, 0));
1049 for(iter=g_slist_nth(list_out,1);iter!=NULL;iter=g_slist_next(iter)) {
1050 /* Find all time requests with the lowest start time in list_out */
1051 guint index_ltime = g_array_index(ltime, guint, 0);
1052 EventsRequest *event_request_ltime = (EventsRequest*)g_slist_nth_data(ltime, 0);
1053 EventsRequest *event_request_list_out = (EventsRequest*)iter->data;
1054
1055 int comp;
1056 comp = ltt_time_compare(event_request_ltime->start_time,
1057 event_request_list_out->start_time);
1058 if(comp == 0)
1059 ltime = g_slist_append(ltime, event_request_list_out);
1060 else if(comp > 0) {
1061 /* Remove all elements from ltime, and add current */
1062 while(ltime != NULL)
1063 ltime = g_slist_delete_link(ltime, g_slist_nth(ltime, 0));
1064 ltime = g_slist_append(ltime, event_request_list_out);
1065 }
501e4e70 1066 }
1067
3bafb436 1068 /* 1.1.2 Find all position requests with the lowest position in list_out
1069 * (lpos)
1070 */
1071 if(g_slist_length(list_out) > 0)
1072 lpos = g_slist_append(lpos, g_slist_nth_data(list_out, 0));
1073 for(iter=g_slist_nth(list_out,1);iter!=NULL;iter=g_slist_next(iter)) {
1074 /* Find all position requests with the lowest position in list_out */
1075 EventsRequest *event_request_lpos = (EventsRequest*)g_slist_nth_data(lpos, 0);
1076 EventsRequest *event_request_list_out = (EventsRequest*)iter->data;
1077
1078 int comp;
1079 if(event_request_lpos->start_position != NULL
1080 && event_request_list_out->start_position != NULL)
1081 {
1082 comp = lttv_traceset_context_pos_pos_compare
1083 (event_request_lpos->start_position,
1084 event_request_list_out->start_position);
1085 } else {
1086 comp = -1;
553d1e7b 1087 }
3bafb436 1088 if(comp == 0)
1089 lpos = g_slist_append(lpos, event_request_list_out);
1090 else if(comp > 0) {
1091 /* Remove all elements from lpos, and add current */
1092 while(lpos != NULL)
1093 lpos = g_slist_delete_link(lpos, g_slist_nth(lpos, 0));
1094 lpos = g_slist_append(lpos, event_request_list_out);
501e4e70 1095 }
1096 }
3bafb436 1097
1098 {
1099 EventsRequest *event_request_lpos = (EventsRequest*)g_slist_nth_data(lpos, 0);
1100 EventsRequest *event_request_ltime = (EventsRequest*)g_slist_nth_data(ltime, 0);
1101 LttTime lpos_start_time;
dd316a11 1102
3bafb436 1103 if(event_request_lpos != NULL
1104 && event_request_lpos->start_position != NULL) {
1105 lpos_start_time = lttv_traceset_context_position_get_time(
1106 event_request_lpos->start_position);
1107 }
1108
1109 /* 1.1.3 If lpos.start time < ltime */
1110 if(event_request_lpos != NULL
1111 && event_request_lpos->start_position != NULL
1112 && ltt_time_compare(lpos_start_time,
1113 event_request_ltime->start_time)<0) {
1114 /* Add lpos to list_in, remove them from list_out */
1115 for(iter=lpos;iter!=NULL;iter=g_slist_next(iter)) {
1116 /* Add to list_in */
1117 EventsRequest *event_request_lpos =
1118 (EventsRequest*)iter->data;
1119
1120 list_in = g_slist_append(list_in, event_request_lpos);
1121 /* Remove from list_out */
1122 list_out = g_slist_remove(list_out, event_request_lpos);
1123 }
1124 } else {
1125 /* 1.1.4 (lpos.start time >= ltime) */
1126 /* Add ltime to list_in, remove them from list_out */
1127
1128 for(iter=ltime;iter!=NULL;iter=g_slist_next(iter)) {
1129 /* Add to list_in */
1130 EventsRequest *event_request_ltime =
1131 (EventsRequest*)iter->data;
1132
1133 list_in = g_slist_append(list_in, event_request_ltime);
1134 /* Remove from list_out */
1135 list_out = g_slist_remove(list_out, event_request_ltime);
1136 }
1137 }
dd316a11 1138 }
3bafb436 1139 g_slist_free(lpos);
1140 g_slist_free(ltime);
dd316a11 1141 }
dd316a11 1142
3bafb436 1143 /* 1.2 Seek */
1144 {
1145 tfc = lttv_traceset_context_get_current_tfc(tsc);
1146 g_assert(g_slist_length(list_in)>0);
1147 EventsRequest *events_request = g_slist_nth_data(list_in, 0);
1148 guint seek_count;
1149
1150 /* 1.2.1 If first request in list_in is a time request */
1151 if(events_request->start_position == NULL) {
1152 /* - If first req in list_in start time != current time */
1153 if(tfc == NULL || ltt_time_compare(events_request->start_time,
1154 tfc->timestamp) != 0)
1155 /* - Seek to that time */
1156 g_debug("SEEK TIME : %lu, %lu", events_request->start_time.tv_sec,
1157 events_request->start_time.tv_nsec);
1158 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
1159 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc),
1160 events_request->start_time);
1161
1162 /* Process the traceset with only state hooks */
1163 seek_count =
1164 lttv_process_traceset_middle(tsc,
1165 events_request->start_time,
1166 G_MAXUINT, NULL);
6ea08962 1167
a43d67ba 1168
3bafb436 1169 } else {
1170 LttTime pos_time;
1171 /* Else, the first request in list_in is a position request */
1172 /* If first req in list_in pos != current pos */
1173 g_assert(events_request->start_position != NULL);
1174 g_debug("SEEK POS time : %lu, %lu",
1175 lttv_traceset_context_position_get_time(
1176 events_request->start_position).tv_sec,
1177 lttv_traceset_context_position_get_time(
1178 events_request->start_position).tv_nsec);
1179
1180 g_debug("SEEK POS context time : %lu, %lu",
1181 lttv_traceset_context_get_current_tfc(tsc)->timestamp.tv_sec,
1182 lttv_traceset_context_get_current_tfc(tsc)->timestamp.tv_nsec);
1183 g_assert(events_request->start_position != NULL);
1184 if(lttv_traceset_context_ctx_pos_compare(tsc,
1185 events_request->start_position) != 0) {
1186 /* 1.2.2.1 Seek to that position */
1187 g_debug("SEEK POSITION");
1188 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
1189 pos_time = lttv_traceset_context_position_get_time(
1190 events_request->start_position);
1191
1192 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc),
1193 pos_time);
1194
1195 /* Process the traceset with only state hooks */
1196 seek_count =
1197 lttv_process_traceset_middle(tsc,
1198 ltt_time_infinite,
1199 G_MAXUINT,
1200 events_request->start_position);
1201 g_assert(lttv_traceset_context_ctx_pos_compare(tsc,
1202 events_request->start_position) == 0);
dd316a11 1203
dd316a11 1204
3bafb436 1205 }
1206 }
1207 }
2d262115 1208
3bafb436 1209 /* 1.3 Add hooks and call before request for all list_in members */
1210 {
1211 GSList *iter = NULL;
dd316a11 1212
3bafb436 1213 for(iter=list_in;iter!=NULL;iter=g_slist_next(iter)) {
1214 EventsRequest *events_request = (EventsRequest*)iter->data;
1215 /* 1.3.1 If !servicing */
2d262115 1216 if(events_request->servicing == FALSE) {
1217 /* - begin request hooks called
1218 * - servicing = TRUE
1219 */
6ea08962 1220 lttv_hooks_call(events_request->before_request, (gpointer)tsc);
2d262115 1221 events_request->servicing = TRUE;
1222 }
3bafb436 1223 /* 1.3.2 call before chunk
1224 * 1.3.3 events hooks added
2d262115 1225 */
1226 lttv_process_traceset_begin(tsc, events_request->before_chunk_traceset,
1227 events_request->before_chunk_trace,
1228 events_request->before_chunk_tracefile,
501e4e70 1229 events_request->event,
1230 events_request->event_by_id);
1231 }
3bafb436 1232 }
1233 } else {
1234 /* 2. Else, list_in is not empty, we continue a read */
1235
1236 {
1237 /* 2.0 For each req of list_in */
1238 GSList *iter = list_in;
1239
1240 while(iter != NULL) {
2d262115 1241
3bafb436 1242 EventsRequest *events_request = (EventsRequest *)iter->data;
1243
1244 /* - Call before chunk
1245 * - events hooks added
1246 */
1247 lttv_process_traceset_begin(tsc, events_request->before_chunk_traceset,
1248 events_request->before_chunk_trace,
1249 events_request->before_chunk_tracefile,
1250 events_request->event,
1251 events_request->event_by_id);
6ea08962 1252
1253 iter = g_slist_next(iter);
1254 }
1255 }
1256
3bafb436 1257 {
1258 tfc = lttv_traceset_context_get_current_tfc(tsc);
1259
1260 /* 2.1 For each req of list_out */
1261 GSList *iter = list_out;
553d1e7b 1262
3bafb436 1263 while(iter != NULL) {
6ea08962 1264
3bafb436 1265 gboolean remove = FALSE;
1266 gboolean free_data = FALSE;
1267 EventsRequest *events_request = (EventsRequest *)iter->data;
1268
1269 /* if req.start time == current context time
1270 * or req.start position == current position*/
1271 if( ltt_time_compare(events_request->start_time,
1272 tfc->timestamp) == 0
1273 ||
1274 (events_request->start_position != NULL
1275 &&
1276 lttv_traceset_context_ctx_pos_compare(tsc,
1277 events_request->start_position) == 0)
1278 ) {
1279 /* - Add to list_in, remove from list_out */
1280 list_in = g_slist_append(list_in, events_request);
1281 remove = TRUE;
1282 free_data = FALSE;
1283
1284 /* - If !servicing */
1285 if(events_request->servicing == FALSE) {
1286 /* - begin request hooks called
1287 * - servicing = TRUE
1288 */
1289 lttv_hooks_call(events_request->before_request, (gpointer)tsc);
1290 events_request->servicing = TRUE;
1291 }
1292 /* call before chunk
1293 * events hooks added
1294 */
1295 lttv_process_traceset_begin(tsc, events_request->before_chunk_traceset,
1296 events_request->before_chunk_trace,
1297 events_request->before_chunk_tracefile,
1298 events_request->event,
1299 events_request->event_by_id);
1300 }
501e4e70 1301
3bafb436 1302 /* Go to next */
1303 if(remove)
1304 {
1305 GSList *remove_iter = iter;
2d262115 1306
3bafb436 1307 iter = g_slist_next(iter);
1308 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
1309 list_out = g_slist_remove_link(list_out, remove_iter);
1310 } else { // not remove
1311 iter = g_slist_next(iter);
1312 }
1313 }
1314 }
1315 }
8f2872f4 1316
3bafb436 1317 /* 3. Find end criterions */
1318 {
1319 /* 3.1 End time */
1320 GSList *iter;
1321
1322 /* 3.1.1 Find lowest end time in list_in */
1323 g_assert(g_slist_length(list_in)>0);
1324 end_time = ((EventsRequest*)g_slist_nth_data(list_in,0))->end_time;
1325
1326 for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) {
1327 EventsRequest *events_request = (EventsRequest*)iter->data;
501e4e70 1328
3bafb436 1329 if(ltt_time_compare(events_request->end_time,
1330 end_time) < 0)
1331 end_time = events_request->end_time;
1332 }
1333
1334 /* 3.1.2 Find lowest start time in list_out */
1335 for(iter=list_out;iter!=NULL;iter=g_slist_next(iter)) {
1336 EventsRequest *events_request = (EventsRequest*)iter->data;
2d262115 1337
3bafb436 1338 if(ltt_time_compare(events_request->start_time,
1339 end_time) < 0)
1340 end_time = events_request->start_time;
1341 }
501e4e70 1342 }
1343
3bafb436 1344 {
1345 /* 3.2 Number of events */
dd316a11 1346
3bafb436 1347 /* 3.2.1 Find lowest number of events in list_in */
1348 GSList *iter;
501e4e70 1349
3bafb436 1350 end_nb_events = ((EventsRequest*)g_slist_nth_data(list_in,0))->num_events;
501e4e70 1351
3bafb436 1352 for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) {
1353 EventsRequest *events_request = (EventsRequest*)iter->data;
501e4e70 1354
3bafb436 1355 if(events_request->num_events < end_nb_events)
1356 end_nb_events = events_request->num_events;
1357 }
501e4e70 1358
3bafb436 1359 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
1360 * num_events */
1361
1362 end_nb_events = MIN(CHUNK_NUM_EVENTS, end_nb_events);
501e4e70 1363 }
501e4e70 1364
3bafb436 1365 {
1366 /* 3.3 End position */
501e4e70 1367
3bafb436 1368 /* 3.3.1 Find lowest end position in list_in */
1369 GSList *iter;
6ea08962 1370
3bafb436 1371 end_position =((EventsRequest*)g_slist_nth_data(list_in,0))->end_position;
6ea08962 1372
3bafb436 1373 for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) {
1374 EventsRequest *events_request = (EventsRequest*)iter->data;
dd316a11 1375
3bafb436 1376 if(events_request->end_position != NULL && end_position != NULL &&
1377 lttv_traceset_context_pos_pos_compare(events_request->end_position,
1378 end_position) <0)
1379 end_position = events_request->end_position;
1380 }
1381 }
1382
1383 {
1384 /* 3.3.2 Find lowest start position in list_out */
1385 GSList *iter;
dd316a11 1386
3bafb436 1387 for(iter=list_out;iter!=NULL;iter=g_slist_next(iter)) {
1388 EventsRequest *events_request = (EventsRequest*)iter->data;
dd316a11 1389
3bafb436 1390 if(events_request->end_position != NULL && end_position != NULL &&
1391 lttv_traceset_context_pos_pos_compare(events_request->end_position,
1392 end_position) <0)
1393 end_position = events_request->end_position;
dd316a11 1394 }
2d262115 1395 }
3bafb436 1396
2d262115 1397 {
3bafb436 1398 /* 4. Call process traceset middle */
1399 g_debug("Calling process traceset middle with %p, %lu sec %lu nsec, %lu nb ev, %p end pos", tsc, end_time.tv_sec, end_time.tv_nsec, end_nb_events, end_position);
1400 count = lttv_process_traceset_middle(tsc, end_time, end_nb_events, end_position);
2d262115 1401
3bafb436 1402 tfc = lttv_traceset_context_get_current_tfc(tsc);
1403 if(tfc != NULL)
1404 g_debug("Context time after middle : %lu, %lu", tfc->timestamp.tv_sec,
1405 tfc->timestamp.tv_nsec);
1406 else
1407 g_debug("End of trace reached after middle.");
2d262115 1408
3bafb436 1409 }
1410 {
1411 /* 5. After process traceset middle */
1412 tfc = lttv_traceset_context_get_current_tfc(tsc);
1413
1414 /* - if current context time > traceset.end time */
1415 if(tfc == NULL || ltt_time_compare(tfc->timestamp,
1416 tsc->time_span.end_time) > 0) {
1417 /* - For each req in list_in */
1418 GSList *iter = list_in;
1419
1420 while(iter != NULL) {
1421
1422 gboolean remove = FALSE;
1423 gboolean free_data = FALSE;
1424 EventsRequest *events_request = (EventsRequest *)iter->data;
1425
1426 /* - Remove events hooks for req
1427 * - Call end chunk for req
1428 */
1429 lttv_process_traceset_end(tsc, events_request->after_chunk_traceset,
1430 events_request->after_chunk_trace,
1431 events_request->after_chunk_tracefile,
1432 events_request->event,
1433 events_request->event_by_id);
1434 /* - Call end request for req */
6ea08962 1435 lttv_hooks_call(events_request->after_request, (gpointer)tsc);
3bafb436 1436
2d262115 1437 /* - remove req from list_in */
1438 /* Destroy the request */
1439 remove = TRUE;
1440 free_data = TRUE;
3bafb436 1441
1442 /* Go to next */
1443 if(remove)
1444 {
1445 GSList *remove_iter = iter;
1446
1447 iter = g_slist_next(iter);
1448 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
1449 list_in = g_slist_remove_link(list_in, remove_iter);
1450 } else { // not remove
1451 iter = g_slist_next(iter);
1452 }
2d262115 1453 }
3bafb436 1454 }
1455 {
1456 /* 5.1 For each req in list_in */
1457 GSList *iter = list_in;
1458
1459 while(iter != NULL) {
501e4e70 1460
3bafb436 1461 gboolean remove = FALSE;
1462 gboolean free_data = FALSE;
1463 EventsRequest *events_request = (EventsRequest *)iter->data;
1464
1465 /* - Remove events hooks for req
1466 * - Call end chunk for req
1467 */
1468 lttv_process_traceset_end(tsc, events_request->after_chunk_traceset,
1469 events_request->after_chunk_trace,
1470 events_request->after_chunk_tracefile,
1471 events_request->event,
1472 events_request->event_by_id);
1473
1474 /* - req.num -= count */
1475 g_assert(events_request->num_events >= count);
1476 events_request->num_events -= count;
1477
1478 g_assert(tfc != NULL);
1479 /* - if req.num == 0
1480 * or
1481 * current context time >= req.end time
1482 * or
1483 * req.end pos == current pos
1484 * or
1485 * req.stop_flag == TRUE
1486 */
1487 if( events_request->num_events == 0
1488 ||
1489 events_request->stop_flag == TRUE
1490 ||
1491 ltt_time_compare(tfc->timestamp,
1492 events_request->end_time) >= 0
1493 ||
1494 (events_request->end_position != NULL
1495 &&
1496 lttv_traceset_context_ctx_pos_compare(tsc,
1497 events_request->end_position) == 0)
1498
1499 ) {
1500 g_assert(events_request->servicing == TRUE);
1501 /* - Call end request for req
1502 * - remove req from list_in */
1503 lttv_hooks_call(events_request->after_request, (gpointer)tsc);
1504 /* - remove req from list_in */
1505 /* Destroy the request */
1506 remove = TRUE;
1507 free_data = TRUE;
1508 }
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 }
1522 }
1523 }
501e4e70 1524 }
dd316a11 1525 /* End of removed servicing loop : leave control to GTK instead. */
1526 // if(gtk_events_pending()) break;
1527 //}
1528
2d262115 1529 /* B. When interrupted between chunks */
501e4e70 1530
501e4e70 1531 {
1532 GSList *iter = list_in;
1533
2d262115 1534 /* 1. for each request in list_in */
501e4e70 1535 while(iter != NULL) {
1536
1537 gboolean remove = FALSE;
1538 gboolean free_data = FALSE;
2d262115 1539 EventsRequest *events_request = (EventsRequest *)iter->data;
501e4e70 1540
1541 /* 1.1. Use current postition as start position */
a1a2b649 1542 if(events_request->start_position != NULL)
1543 lttv_traceset_context_position_destroy(events_request->start_position);
b052368a 1544 events_request->start_position = lttv_traceset_context_position_new();
501e4e70 1545 lttv_traceset_context_position_save(tsc, events_request->start_position);
1546
1547 /* 1.2. Remove start time */
0aa6c3a1 1548 events_request->start_time = ltt_time_infinite;
501e4e70 1549
2d262115 1550 /* 1.3. Move from list_in to list_out */
501e4e70 1551 remove = TRUE;
1552 free_data = FALSE;
1553 list_out = g_slist_append(list_out, events_request);
1554
501e4e70 1555 /* Go to next */
1556 if(remove)
8f2872f4 1557 {
501e4e70 1558 GSList *remove_iter = iter;
1559
1560 iter = g_slist_next(iter);
b052368a 1561 if(free_data) events_request_free((EventsRequest*)remove_iter->data);
501e4e70 1562 list_in = g_slist_remove_link(list_in, remove_iter);
1563 } else { // not remove
1564 iter = g_slist_next(iter);
8f2872f4 1565 }
1566 }
a43d67ba 1567
501e4e70 1568
1569 }
b052368a 1570
1571 /* C Unlock Traces */
1572 {
1573 //lttv_process_traceset_get_sync_data(tsc);
1574
1575 guint iter_trace;
1576
1577 for(iter_trace=0;
1578 iter_trace<lttv_traceset_number(tsc->ts);
1579 iter_trace++) {
1580 LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
1581
1582 lttvwindowtraces_unlock(trace_v);
1583 }
1584 }
501e4e70 1585
a0577796 1586#if 0
abe346a3 1587 //set the cursor back to normal
a8c0f09d 1588 gdk_window_set_cursor(win, NULL);
a0577796 1589#endif //0
501e4e70 1590
2d262115 1591 g_assert(g_slist_length(list_in) == 0);
6ea08962 1592
2d262115 1593 if( g_slist_length(list_out) == 0 ) {
501e4e70 1594 /* Put tab's request pending flag back to normal */
2d262115 1595 tab->events_request_pending = FALSE;
b052368a 1596 g_debug("remove the idle fct");
501e4e70 1597 return FALSE; /* Remove the idle function */
1598 }
b052368a 1599 g_debug("leave the idle fct");
501e4e70 1600 return TRUE; /* Leave the idle function */
b052368a 1601
1602 /* We do not use simili-round-robin, it may require to read 1 meg buffers
1603 * again and again if many tracesets use the same tracefiles. */
1604 /* Hack for round-robin idle functions */
1605 /* It will put the idle function at the end of the pool */
1606 /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
1607 (GSourceFunc)execute_events_requests,
1608 tab,
1609 NULL);
1610 return FALSE;
1611 */
202f6c8f 1612}
1613
6ea08962 1614#undef list_out
501e4e70 1615
abe346a3 1616
1617/* add_trace_into_traceset_selector, each instance of a viewer has an associated
1618 * selector (filter), when a trace is added into traceset, the selector should
1619 * reflect the change. The function is used to update the selector
1620 */
b052368a 1621#if 0
1622void add_trace_into_traceset_selector(GtkWidget * paned, LttTrace * t)
49bf71b5 1623{
ed3b99b6 1624 int j, k, m, nb_tracefile, nb_control, nb_per_cpu, nb_facility, nb_event;
49bf71b5 1625 LttvTracesetSelector * s;
1626 LttvTraceSelector * trace;
1627 LttvTracefileSelector * tracefile;
ed3b99b6 1628 LttvEventtypeSelector * eventtype;
49bf71b5 1629 LttTracefile * tf;
1630 GtkWidget * w;
ed3b99b6 1631 LttFacility * fac;
1632 LttEventType * et;
49bf71b5 1633
b052368a 1634 w = gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned));
49bf71b5 1635 while(w){
1636 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
49bf71b5 1637
abe346a3 1638 if(s){
1639 trace = lttv_trace_selector_new(t);
1640 lttv_traceset_selector_trace_add(s, trace);
1641
1642 nb_facility = ltt_trace_facility_number(t);
1643 for(k=0;k<nb_facility;k++){
1644 fac = ltt_trace_facility_get(t,k);
1645 nb_event = (int) ltt_facility_eventtype_number(fac);
1646 for(m=0;m<nb_event;m++){
1647 et = ltt_facility_eventtype_get(fac,m);
1648 eventtype = lttv_eventtype_selector_new(et);
1649 lttv_trace_selector_eventtype_add(trace, eventtype);
1650 }
1651 }
1652
1653 nb_control = ltt_trace_control_tracefile_number(t);
1654 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(t);
1655 nb_tracefile = nb_control + nb_per_cpu;
1656
1657 for(j = 0 ; j < nb_tracefile ; j++) {
1658 if(j < nb_control)
1659 tf = ltt_trace_control_tracefile_get(t, j);
1660 else
1661 tf = ltt_trace_per_cpu_tracefile_get(t, j - nb_control);
1662 tracefile = lttv_tracefile_selector_new(tf);
1663 lttv_trace_selector_tracefile_add(trace, tracefile);
1664 lttv_eventtype_selector_copy(trace, tracefile);
1665 }
1666 }else g_warning("Module does not support filtering\n");
49bf71b5 1667
b052368a 1668 w = gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned));
49bf71b5 1669 }
1670}
b052368a 1671#endif //0
abe346a3 1672
4266dc7f 1673static void lttvwindow_add_trace(Tab *tab, LttvTrace *trace_v)
1674{
1675 LttvTraceset *traceset = tab->traceset_info->traceset;
1676 guint i;
91fd6881 1677 guint num_traces = lttv_traceset_number(traceset);
4266dc7f 1678
a1a2b649 1679 //Verify if trace is already present.
91fd6881 1680 for(i=0; i<num_traces; i++)
a1a2b649 1681 {
1682 LttvTrace * trace = lttv_traceset_get(traceset, i);
1683 if(trace == trace_v)
1684 return;
1685 }
1686
4266dc7f 1687 //Keep a reference to the traces so they are not freed.
1688 for(i=0; i<lttv_traceset_number(traceset); i++)
1689 {
1690 LttvTrace * trace = lttv_traceset_get(traceset, i);
1691 lttv_trace_ref(trace);
1692 }
1693
1694 //remove state update hooks
1695 lttv_state_remove_event_hooks(
1696 (LttvTracesetState*)tab->traceset_info->traceset_context);
1697
1698 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1699 tab->traceset_info->traceset_context));
1700 g_object_unref(tab->traceset_info->traceset_context);
1701
1702 lttv_traceset_add(traceset, trace_v);
a1a2b649 1703 lttv_trace_ref(trace_v); /* local ref */
4266dc7f 1704
1705 /* Create new context */
1706 tab->traceset_info->traceset_context =
1707 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1708 lttv_context_init(
1709 LTTV_TRACESET_CONTEXT(tab->traceset_info->
1710 traceset_context),
1711 traceset);
6ea08962 1712
6ea08962 1713
4266dc7f 1714 //add state update hooks
1715 lttv_state_add_event_hooks(
1716 (LttvTracesetState*)tab->traceset_info->traceset_context);
1717 //Remove local reference to the traces.
1718 for(i=0; i<lttv_traceset_number(traceset); i++)
1719 {
1720 LttvTrace * trace = lttv_traceset_get(traceset, i);
1721 lttv_trace_unref(trace);
1722 }
1723
b052368a 1724 //FIXME
1725 //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
4266dc7f 1726}
1727
abe346a3 1728/* add_trace adds a trace into the current traceset. It first displays a
1729 * directory selection dialogue to let user choose a trace, then recreates
1730 * tracset_context, and redraws all the viewer of the current tab
1731 */
1732
561eba2a 1733void add_trace(GtkWidget * widget, gpointer user_data)
1734{
2176f952 1735 LttTrace *trace;
1736 LttvTrace * trace_v;
1737 LttvTraceset * traceset;
94dcfb9e 1738 const char * dir;
a1a2b649 1739 char abs_path[PATH_MAX];
2176f952 1740 gint id;
a43d67ba 1741 gint i;
bca3b81f 1742 MainWindow * mw_data = get_window_data_struct(widget);
6ced96ef 1743 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1744
1745 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1746 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1747 Tab *tab;
1748
1749 if(!page) {
1750 tab = create_new_tab(widget, NULL);
1751 } else {
1752 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1753 }
4266dc7f 1754
68b48a45 1755 GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
1756 gtk_dir_selection_hide_fileop_buttons(file_selector);
4266dc7f 1757
3658a338 1758 if(remember_trace_dir[0] != '\0')
1759 gtk_dir_selection_set_filename(file_selector, remember_trace_dir);
2176f952 1760
68b48a45 1761 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2176f952 1762 switch(id){
1763 case GTK_RESPONSE_ACCEPT:
1764 case GTK_RESPONSE_OK:
68b48a45 1765 dir = gtk_dir_selection_get_dir (file_selector);
a1a2b649 1766 strncpy(remember_trace_dir, dir, PATH_MAX);
a43d67ba 1767 if(!dir || strlen(dir) == 0){
1768 gtk_widget_destroy((GtkWidget*)file_selector);
1769 break;
284675e3 1770 }
a1a2b649 1771 get_absolute_pathname(dir, abs_path);
1772 trace_v = lttvwindowtraces_get_trace_by_name(abs_path);
1773 if(trace_v == NULL) {
1774 trace = ltt_trace_open(abs_path);
2a74fbf4 1775 if(trace == NULL) {
1776 g_warning("cannot open trace %s", abs_path);
1777 } else {
1778 trace_v = lttv_trace_new(trace);
1779 lttvwindowtraces_add_trace(trace_v);
1780 lttvwindow_add_trace(tab, trace_v);
1781 }
1782 } else {
1783 lttvwindow_add_trace(tab, trace_v);
a1a2b649 1784 }
c2619a30 1785
49bf71b5 1786 gtk_widget_destroy((GtkWidget*)file_selector);
1787
1788 //update current tab
a43d67ba 1789 //update_traceset(mw_data);
21e8c385 1790
a43d67ba 1791 /* Call the updatetraceset hooks */
1792
4266dc7f 1793 traceset = tab->traceset_info->traceset;
1794 SetTraceset(tab, traceset);
a43d67ba 1795 // in expose now call_pending_read_hooks(mw_data);
1796
4266dc7f 1797 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
49bf71b5 1798 break;
2176f952 1799 case GTK_RESPONSE_REJECT:
1800 case GTK_RESPONSE_CANCEL:
1801 default:
68b48a45 1802 gtk_widget_destroy((GtkWidget*)file_selector);
2176f952 1803 break;
1804 }
49bf71b5 1805}
1806
abe346a3 1807
1808/* remove_trace_into_traceset_selector, each instance of a viewer has an associated
1809 * selector (filter), when a trace is remove from traceset, the selector should
1810 * reflect the change. The function is used to update the selector
1811 */
b052368a 1812#if 0
1813void remove_trace_from_traceset_selector(GtkWidget * paned, unsigned i)
49bf71b5 1814{
1815 LttvTracesetSelector * s;
1816 LttvTraceSelector * t;
1817 GtkWidget * w;
1818
b052368a 1819 w = gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(paned));
49bf71b5 1820 while(w){
1821 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
abe346a3 1822 if(s){
1823 t = lttv_traceset_selector_trace_get(s,i);
1824 lttv_traceset_selector_trace_remove(s, i);
1825 lttv_trace_selector_destroy(t);
1826 }g_warning("Module dose not support filtering\n");
b052368a 1827 w = gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(paned));
49bf71b5 1828 }
561eba2a 1829}
b052368a 1830#endif //0
abe346a3 1831
1832/* remove_trace removes a trace from the current traceset if all viewers in
1833 * the current tab are not interested in the trace. It first displays a
1834 * dialogue, which shows all traces in the current traceset, to let user choose
1835 * a trace, then it checks if all viewers unselect the trace, if it is true,
1836 * it will remove the trace, recreate the traceset_contex,
1837 * and redraws all the viewer of the current tab. If there is on trace in the
1838 * current traceset, it will delete all viewers of the current tab
1839 */
1840
b052368a 1841// MD : no filter version.
1842void remove_trace(GtkWidget *widget, gpointer user_data)
1843{
1844 LttTrace *trace;
1845 LttvTrace * trace_v;
1846 LttvTraceset * traceset;
1847 gint i, j, nb_trace, index=-1;
1848 char ** name, *remove_trace_name;
1849 MainWindow * mw_data = get_window_data_struct(widget);
1850 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1851
1852 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1853 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1854 Tab *tab;
1855
1856 if(!page) {
1857 return;
1858 } else {
1859 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1860 }
1861
1862 nb_trace =lttv_traceset_number(tab->traceset_info->traceset);
1863 name = g_new(char*,nb_trace);
1864 for(i = 0; i < nb_trace; i++){
1865 trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
1866 trace = lttv_trace(trace_v);
1867 name[i] = ltt_trace_name(trace);
1868 }
1869
1870 remove_trace_name = get_remove_trace(name, nb_trace);
1871
1872
1873 if(remove_trace_name){
1874
1875 /* yuk, cut n paste from old code.. should be better (MD)*/
1876 for(i = 0; i<nb_trace; i++) {
1877 if(strcmp(remove_trace_name,name[i]) == 0){
1878 index = i;
1879 }
1880 }
1881
1882 traceset = tab->traceset_info->traceset;
1883 //Keep a reference to the traces so they are not freed.
1884 for(j=0; j<lttv_traceset_number(traceset); j++)
1885 {
1886 LttvTrace * trace = lttv_traceset_get(traceset, j);
1887 lttv_trace_ref(trace);
1888 }
1889
1890 //remove state update hooks
1891 lttv_state_remove_event_hooks(
1892 (LttvTracesetState*)tab->traceset_info->traceset_context);
1893 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
1894 g_object_unref(tab->traceset_info->traceset_context);
1895
1896 trace_v = lttv_traceset_get(traceset, index);
1897
b052368a 1898 lttv_traceset_remove(traceset, index);
1899 lttv_trace_unref(trace_v); // Remove local reference
1900
1ba187d3 1901 if(lttv_trace_get_ref_number(trace_v) <= 1) {
1902 /* ref 1 : lttvwindowtraces only*/
1903 ltt_trace_close(lttv_trace(trace_v));
1904 /* lttvwindowtraces_remove_trace takes care of destroying
1905 * the traceset linked with the trace_v and also of destroying
1906 * the trace_v at the same time.
1907 */
1908 lttvwindowtraces_remove_trace(trace_v);
1909 }
b052368a 1910
1911 tab->traceset_info->traceset_context =
1912 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1913 lttv_context_init(
1914 LTTV_TRACESET_CONTEXT(tab->
1915 traceset_info->traceset_context),traceset);
1916 //add state update hooks
1917 lttv_state_add_event_hooks(
1918 (LttvTracesetState*)tab->traceset_info->traceset_context);
1919
1920 //Remove local reference to the traces.
1921 for(j=0; j<lttv_traceset_number(traceset); j++)
1922 {
1923 LttvTrace * trace = lttv_traceset_get(traceset, j);
1924 lttv_trace_unref(trace);
1925 }
1926
1927 SetTraceset(tab, (gpointer)traceset);
1928 }
1929 g_free(name);
1930}
1931
1932#if 0
561eba2a 1933void remove_trace(GtkWidget * widget, gpointer user_data)
1934{
2176f952 1935 LttTrace *trace;
1936 LttvTrace * trace_v;
1937 LttvTraceset * traceset;
a43d67ba 1938 gint i, j, nb_trace;
2176f952 1939 char ** name, *remove_trace_name;
bca3b81f 1940 MainWindow * mw_data = get_window_data_struct(widget);
49bf71b5 1941 LttvTracesetSelector * s;
1942 LttvTraceSelector * t;
1943 GtkWidget * w;
1944 gboolean selected;
6ced96ef 1945 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1946
1947 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1948 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1949 Tab *tab;
1950
1951 if(!page) {
1952 return;
1953 } else {
1954 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1955 }
1956
4266dc7f 1957 nb_trace =lttv_traceset_number(tab->traceset_info->traceset);
2176f952 1958 name = g_new(char*,nb_trace);
1959 for(i = 0; i < nb_trace; i++){
4266dc7f 1960 trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
2176f952 1961 trace = lttv_trace(trace_v);
a5dcde2f 1962 name[i] = ltt_trace_name(trace);
2176f952 1963 }
1964
1965 remove_trace_name = get_remove_trace(name, nb_trace);
1966
1967 if(remove_trace_name){
1968 for(i=0; i<nb_trace; i++){
1969 if(strcmp(remove_trace_name,name[i]) == 0){
6ced96ef 1970 //unselect the trace from the current viewer
b052368a 1971 //FIXME
1972 w = gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab->multivpaned));
6ced96ef 1973 if(w){
1974 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1975 if(s){
1976 t = lttv_traceset_selector_trace_get(s,i);
1977 lttv_trace_selector_set_selected(t, FALSE);
1978 }
1979
1980 //check if other viewers select the trace
b052368a 1981 w = gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab->multivpaned));
6ced96ef 1982 while(w){
1983 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1984 if(s){
1985 t = lttv_traceset_selector_trace_get(s,i);
1986 selected = lttv_trace_selector_get_selected(t);
1987 if(selected)break;
1988 }
b052368a 1989 w = gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab->multivpaned));
6ced96ef 1990 }
1991 }else selected = FALSE;
49bf71b5 1992
6ced96ef 1993 //if no viewer selects the trace, remove it
1994 if(!selected){
b052368a 1995 remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), i);
49bf71b5 1996
6ced96ef 1997 traceset = tab->traceset_info->traceset;
1998 //Keep a reference to the traces so they are not freed.
1999 for(j=0; j<lttv_traceset_number(traceset); j++)
2000 {
2001 LttvTrace * trace = lttv_traceset_get(traceset, j);
2002 lttv_trace_ref(trace);
2003 }
a43d67ba 2004
6ced96ef 2005 //remove state update hooks
2006 lttv_state_remove_event_hooks(
2007 (LttvTracesetState*)tab->traceset_info->traceset_context);
2008 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
2009 g_object_unref(tab->traceset_info->traceset_context);
a43d67ba 2010
a43d67ba 2011
6ced96ef 2012 trace_v = lttv_traceset_get(traceset, i);
a43d67ba 2013
a1a2b649 2014 if(lttv_trace_get_ref_number(trace_v) <= 2) {
2015 /* ref 2 : traceset, local */
2016 lttvwindowtraces_remove_trace(trace_v);
6ced96ef 2017 ltt_trace_close(lttv_trace(trace_v));
a1a2b649 2018 }
6ced96ef 2019
2020 lttv_traceset_remove(traceset, i);
2021 lttv_trace_unref(trace_v); // Remove local reference
c2619a30 2022
6ced96ef 2023 if(!lttv_trace_get_ref_number(trace_v))
2024 lttv_trace_destroy(trace_v);
2025
2026 tab->traceset_info->traceset_context =
2027 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
2028 lttv_context_init(
2029 LTTV_TRACESET_CONTEXT(tab->
2030 traceset_info->traceset_context),traceset);
2031 //add state update hooks
2032 lttv_state_add_event_hooks(
2033 (LttvTracesetState*)tab->traceset_info->traceset_context);
2034
2035 //Remove local reference to the traces.
2036 for(j=0; j<lttv_traceset_number(traceset); j++)
2037 {
2038 LttvTrace * trace = lttv_traceset_get(traceset, j);
2039 lttv_trace_unref(trace);
2040 }
a43d67ba 2041
a43d67ba 2042
6ced96ef 2043 //update current tab
2044 //update_traceset(mw_data);
313bd6fc 2045 //if(nb_trace > 1){
6ced96ef 2046
313bd6fc 2047 SetTraceset(tab, (gpointer)traceset);
6ced96ef 2048 // in expose now call_pending_read_hooks(mw_data);
2049
2050 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
313bd6fc 2051 //}else{
2052 // if(tab){
2053 // while(tab->multi_vpaned->num_children){
2054 // gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
2055 // }
2056 // }
2057 //}
6ced96ef 2058 }
2059 break;
2176f952 2060 }
2061 }
2062 }
2063
2064 g_free(name);
561eba2a 2065}
b052368a 2066#endif //0
abe346a3 2067
9878c8a4 2068/* Redraw all the viewers in the current tab */
2069void redraw(GtkWidget *widget, gpointer user_data)
2070{
2071 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2072 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2073 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2074 Tab *tab;
2075 if(!page) {
2076 return;
2077 } else {
2078 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
2079 }
2080
2081 LttvHooks * tmp;
2082 LttvAttributeValue value;
2083
2084 g_assert(lttv_iattribute_find_by_path(tab->attributes, "hooks/redraw", LTTV_POINTER, &value));
2085
2086 tmp = (LttvHooks*)*(value.v_pointer);
c07e9b26 2087 if(tmp != NULL)
2088 lttv_hooks_call(tmp,NULL);
9878c8a4 2089}
2090
2091
2092void continue_processing(GtkWidget *widget, gpointer user_data)
2093{
2094 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2095 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2096 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2097 Tab *tab;
2098 if(!page) {
2099 return;
2100 } else {
2101 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
2102 }
2103
2104 LttvHooks * tmp;
2105 LttvAttributeValue value;
2106
2107 g_assert(lttv_iattribute_find_by_path(tab->attributes,
2108 "hooks/continue", LTTV_POINTER, &value));
2109
2110 tmp = (LttvHooks*)*(value.v_pointer);
c07e9b26 2111 if(tmp != NULL)
2112 lttv_hooks_call(tmp,NULL);
9878c8a4 2113}
2114
2115/* Stop the processing for the calling main window's current tab.
2116 * It removes every processing requests that are in its list. It does not call
2117 * the end request hooks, because the request is not finished.
2118 */
2119
2120void stop_processing(GtkWidget *widget, gpointer user_data)
2121{
2122 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2123 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2124 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2125 Tab *tab;
2126 if(!page) {
2127 return;
2128 } else {
2129 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
2130 }
a0577796 2131 GSList *iter = tab->events_requests;
9878c8a4 2132
2133 while(iter != NULL) {
2134 GSList *remove_iter = iter;
2135 iter = g_slist_next(iter);
2136
2137 g_free(remove_iter->data);
a0577796 2138 tab->events_requests =
2139 g_slist_remove_link(tab->events_requests, remove_iter);
9878c8a4 2140 }
a0577796 2141 tab->events_request_pending = FALSE;
2142 g_idle_remove_by_data(tab);
2143 g_assert(g_slist_length(tab->events_requests) == 0);
9878c8a4 2144}
2145
2146
abe346a3 2147/* save will save the traceset to a file
a43d67ba 2148 * Not implemented yet FIXME
abe346a3 2149 */
2150
561eba2a 2151void save(GtkWidget * widget, gpointer user_data)
2152{
2153 g_printf("Save\n");
2154}
2155
2156void save_as(GtkWidget * widget, gpointer user_data)
2157{
2158 g_printf("Save as\n");
2159}
2160
abe346a3 2161
2162/* zoom will change the time_window of all the viewers of the
2163 * current tab, and redisplay them. The main functionality is to
2164 * determine the new time_window of the current tab
2165 */
2166
1f1ae829 2167void zoom(GtkWidget * widget, double size)
2168{
b052368a 2169 TimeInterval time_span;
a43d67ba 2170 TimeWindow new_time_window;
2171 LttTime current_time, time_delta, time_s, time_e, time_tmp;
1f1ae829 2172 MainWindow * mw_data = get_window_data_struct(widget);
4266dc7f 2173 LttvTracesetContext *tsc;
6ced96ef 2174 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
2175
2176 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2177 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2178 Tab *tab;
2179
2180 if(!page) {
2181 return;
2182 } else {
2183 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
2184 }
1f1ae829 2185
fda16332 2186 if(size == 1) return;
2187
4266dc7f 2188 tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
b052368a 2189 time_span = tsc->time_span;
501e4e70 2190 new_time_window = tab->time_window;
2191 current_time = tab->current_time;
1f1ae829 2192
b052368a 2193 time_delta = ltt_time_sub(time_span.end_time,time_span.start_time);
1f1ae829 2194 if(size == 0){
b052368a 2195 new_time_window.start_time = time_span.start_time;
a43d67ba 2196 new_time_window.time_width = time_delta;
1f1ae829 2197 }else{
a43d67ba 2198 new_time_window.time_width = ltt_time_div(new_time_window.time_width, size);
2199 if(ltt_time_compare(new_time_window.time_width,time_delta) > 0)
2200 { /* Case where zoom out is bigger than trace length */
b052368a 2201 new_time_window.start_time = time_span.start_time;
a43d67ba 2202 new_time_window.time_width = time_delta;
a8c0f09d 2203 }
a43d67ba 2204 else
2205 {
2206 /* Center the image on the current time */
a43d67ba 2207 new_time_window.start_time =
2208 ltt_time_sub(current_time, ltt_time_div(new_time_window.time_width, 2.0));
2209 /* If on borders, don't fall off */
b052368a 2210 if(ltt_time_compare(new_time_window.start_time, time_span.start_time) <0)
a43d67ba 2211 {
b052368a 2212 new_time_window.start_time = time_span.start_time;
a43d67ba 2213 }
2214 else
2215 {
2216 if(ltt_time_compare(
2217 ltt_time_add(new_time_window.start_time, new_time_window.time_width),
b052368a 2218 time_span.end_time) > 0)
a43d67ba 2219 {
2220 new_time_window.start_time =
b052368a 2221 ltt_time_sub(time_span.end_time, new_time_window.time_width);
a43d67ba 2222 }
2223 }
2224
1f1ae829 2225 }
1f1ae829 2226 }
a43d67ba 2227
f02b5e22 2228 if(ltt_time_compare(new_time_window.time_width, ltt_time_zero) == 0) {
2229 g_warning("Zoom more than 1 ns impossible");
b052368a 2230 } else {
e800cf84 2231 time_change_manager(tab, new_time_window);
b052368a 2232 }
1f1ae829 2233}
2234
561eba2a 2235void zoom_in(GtkWidget * widget, gpointer user_data)
2236{
1f1ae829 2237 zoom(widget, 2);
561eba2a 2238}
2239
2240void zoom_out(GtkWidget * widget, gpointer user_data)
2241{
1f1ae829 2242 zoom(widget, 0.5);
561eba2a 2243}
2244
2245void zoom_extended(GtkWidget * widget, gpointer user_data)
2246{
1f1ae829 2247 zoom(widget, 0);
561eba2a 2248}
2249
2250void go_to_time(GtkWidget * widget, gpointer user_data)
2251{
e800cf84 2252 g_printf("Go to time\n");
561eba2a 2253}
2254
2255void show_time_frame(GtkWidget * widget, gpointer user_data)
2256{
2257 g_printf("Show time frame\n");
2258}
2259
2260
2261/* callback function */
2262
2263void
2264on_empty_traceset_activate (GtkMenuItem *menuitem,
2265 gpointer user_data)
2266{
68b48a45 2267 create_new_window((GtkWidget*)menuitem, user_data, FALSE);
561eba2a 2268}
2269
2270
2271void
2272on_clone_traceset_activate (GtkMenuItem *menuitem,
2273 gpointer user_data)
2274{
68b48a45 2275 create_new_window((GtkWidget*)menuitem, user_data, TRUE);
561eba2a 2276}
2277
abe346a3 2278
2279/* create_new_tab calls create_tab to construct a new tab in the main window
2280 */
2281
6ced96ef 2282Tab *create_new_tab(GtkWidget* widget, gpointer user_data){
a1a2b649 2283 gchar label[PATH_MAX];
2901f314 2284 MainWindow * mw_data = get_window_data_struct(widget);
4266dc7f 2285
2901f314 2286 GtkNotebook * notebook = (GtkNotebook *)lookup_widget(widget, "MNotebook");
561eba2a 2287 if(notebook == NULL){
2288 g_printf("Notebook does not exist\n");
6ced96ef 2289 return NULL;
2290 }
2291 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2292 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2293 Tab *copy_tab;
2294
2295 if(!page) {
2296 copy_tab = NULL;
2297 } else {
2298 copy_tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
561eba2a 2299 }
4266dc7f 2300
6b1d3120 2301 strcpy(label,"Page");
eb38aea5 2302 if(get_label(mw_data, label,"Get the name of the tab","Please input tab's name"))
6ced96ef 2303 return (create_tab (mw_data, copy_tab, notebook, label));
561eba2a 2304}
2305
2901f314 2306void
2307on_tab_activate (GtkMenuItem *menuitem,
2308 gpointer user_data)
2309{
2310 create_new_tab((GtkWidget*)menuitem, user_data);
2311}
2312
561eba2a 2313
2314void
2315on_open_activate (GtkMenuItem *menuitem,
2316 gpointer user_data)
2317{
2318 open_traceset((GtkWidget*)menuitem, user_data);
2319}
2320
2321
2322void
2323on_close_activate (GtkMenuItem *menuitem,
2324 gpointer user_data)
2325{
bca3b81f 2326 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
68b48a45 2327 main_window_destructor(mw_data);
561eba2a 2328}
2329
2330
4266dc7f 2331/* remove the current tab from the main window
abe346a3 2332 */
2333
561eba2a 2334void
27a559b9 2335on_close_tab_activate (GtkWidget *widget,
561eba2a 2336 gpointer user_data)
2337{
4266dc7f 2338 gint page_num;
2061e03d 2339 GtkWidget * notebook;
4266dc7f 2340 GtkWidget * page;
27a559b9 2341 MainWindow * mw_data = get_window_data_struct(widget);
2342 notebook = lookup_widget(widget, "MNotebook");
2061e03d 2343 if(notebook == NULL){
2344 g_printf("Notebook does not exist\n");
2345 return;
2346 }
4266dc7f 2347
2348 page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
2061e03d 2349
4266dc7f 2350 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
2061e03d 2351
561eba2a 2352}
2353
27a559b9 2354void
2355on_close_tab_X_clicked (GtkWidget *widget,
2356 gpointer user_data)
2357{
2358 gint page_num;
2359 GtkWidget *notebook = lookup_widget(widget, "MNotebook");
2360 if(notebook == NULL){
2361 g_printf("Notebook does not exist\n");
2362 return;
2363 }
2364
2365 if((page_num = gtk_notebook_page_num(GTK_NOTEBOOK(notebook), widget)) != -1)
2366 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
2367
2368}
2369
561eba2a 2370
2371void
2372on_add_trace_activate (GtkMenuItem *menuitem,
2373 gpointer user_data)
2374{
2375 add_trace((GtkWidget*)menuitem, user_data);
2376}
2377
2378
2379void
2380on_remove_trace_activate (GtkMenuItem *menuitem,
2381 gpointer user_data)
2382{
2383 remove_trace((GtkWidget*)menuitem, user_data);
2384}
2385
2386
2387void
2388on_save_activate (GtkMenuItem *menuitem,
2389 gpointer user_data)
2390{
2391 save((GtkWidget*)menuitem, user_data);
2392}
2393
2394
2395void
2396on_save_as_activate (GtkMenuItem *menuitem,
2397 gpointer user_data)
2398{
2399 save_as((GtkWidget*)menuitem, user_data);
2400}
2401
2402
2403void
2404on_quit_activate (GtkMenuItem *menuitem,
2405 gpointer user_data)
2406{
2061e03d 2407 gtk_main_quit ();
561eba2a 2408}
2409
2410
2411void
2412on_cut_activate (GtkMenuItem *menuitem,
2413 gpointer user_data)
2414{
2415 g_printf("Cut\n");
2416}
2417
2418
2419void
2420on_copy_activate (GtkMenuItem *menuitem,
2421 gpointer user_data)
2422{
2423 g_printf("Copye\n");
2424}
2425
2426
2427void
2428on_paste_activate (GtkMenuItem *menuitem,
2429 gpointer user_data)
2430{
2431 g_printf("Paste\n");
2432}
2433
2434
2435void
2436on_delete_activate (GtkMenuItem *menuitem,
2437 gpointer user_data)
2438{
2439 g_printf("Delete\n");
2440}
2441
2442
2443void
2444on_zoom_in_activate (GtkMenuItem *menuitem,
2445 gpointer user_data)
2446{
2447 zoom_in((GtkWidget*)menuitem, user_data);
2448}
2449
2450
2451void
2452on_zoom_out_activate (GtkMenuItem *menuitem,
2453 gpointer user_data)
2454{
2455 zoom_out((GtkWidget*)menuitem, user_data);
2456}
2457
2458
2459void
2460on_zoom_extended_activate (GtkMenuItem *menuitem,
2461 gpointer user_data)
2462{
2463 zoom_extended((GtkWidget*)menuitem, user_data);
2464}
2465
2466
2467void
2468on_go_to_time_activate (GtkMenuItem *menuitem,
2469 gpointer user_data)
2470{
2471 go_to_time((GtkWidget*)menuitem, user_data);
2472}
2473
2474
2475void
2476on_show_time_frame_activate (GtkMenuItem *menuitem,
2477 gpointer user_data)
2478{
2479 show_time_frame((GtkWidget*)menuitem, user_data);
2480}
2481
2482
2483void
2484on_move_viewer_up_activate (GtkMenuItem *menuitem,
2485 gpointer user_data)
2486{
2487 move_up_viewer((GtkWidget*)menuitem, user_data);
2488}
2489
2490
2491void
2492on_move_viewer_down_activate (GtkMenuItem *menuitem,
2493 gpointer user_data)
2494{
2495 move_down_viewer((GtkWidget*)menuitem, user_data);
2496}
2497
2498
2499void
2500on_remove_viewer_activate (GtkMenuItem *menuitem,
2501 gpointer user_data)
2502{
2503 delete_viewer((GtkWidget*)menuitem, user_data);
2504}
2505
b052368a 2506#if 0
49bf71b5 2507void
2508on_trace_filter_activate (GtkMenuItem *menuitem,
2509 gpointer user_data)
2510{
2511 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2512 LttvTracesetSelector * s;
4266dc7f 2513 GtkWidget * w;
6ced96ef 2514 GtkWidget * notebook = lookup_widget(GTK_WIDGET(menuitem), "MNotebook");
2515
2516 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
2517 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
2518 Tab *tab;
2519
2520 if(!page) {
2521 return;
2522 } else {
2523 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
2524 }
4266dc7f 2525
b052368a 2526 w = gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab->multivpaned));
49bf71b5 2527
2528 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
2529 if(!s){
2530 g_printf("There is no viewer yet\n");
2531 return;
2532 }
a8c0f09d 2533 if(get_filter_selection(s, "Configure trace and tracefile filter", "Select traces and tracefiles")){
a43d67ba 2534 //FIXME report filter change
2535 //update_traceset(mw_data);
2536 //call_pending_read_hooks(mw_data);
4266dc7f 2537 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
a8c0f09d 2538 }
49bf71b5 2539}
b052368a 2540#endif //0
49bf71b5 2541
2542void
2543on_trace_facility_activate (GtkMenuItem *menuitem,
2544 gpointer user_data)
2545{
2546 g_printf("Trace facility selector: %s\n");
2547}
561eba2a 2548
abe346a3 2549
b052368a 2550/* Dispaly a file selection dialogue to let user select a library, then call
2551 * lttv_library_load().
2552 */
2553
2554void
2555on_load_library_activate (GtkMenuItem *menuitem,
2556 gpointer user_data)
2557{
2558 GError *error = NULL;
2559 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2560
2561 gchar load_module_path_alter[PATH_MAX];
2562 {
2563 GPtrArray *name;
2564 guint nb,i;
2565 gchar *load_module_path;
2566 name = g_ptr_array_new();
2567 nb = lttv_library_path_number();
2568 /* ask for the library path */
2569
2570 for(i=0;i<nb;i++){
2571 gchar *path;
2572 path = lttv_library_path_get(i);
2573 g_ptr_array_add(name, path);
2574 }
2575
2576 load_module_path = get_selection((char **)(name->pdata), name->len,
2577 "Select a library path", "Library paths");
2578 if(load_module_path != NULL)
2579 strncpy(load_module_path_alter, load_module_path, PATH_MAX-1); // -1 for /
2580
2581 g_ptr_array_free(name, TRUE);
2582
2583 if(load_module_path == NULL) return;
2584 }
2585
2586 {
2587 /* Make sure the module path ends with a / */
2588 gchar *ptr = load_module_path_alter;
2589
2590 ptr = strchr(ptr, '\0');
2591
2592 if(*(ptr-1) != '/') {
2593 *ptr = '/';
2594 *(ptr+1) = '\0';
2595 }
2596 }
2597
2598 {
2599 /* Ask for the library to load : list files in the previously selected
2600 * directory */
2601 gchar str[PATH_MAX];
2602 gchar ** dir;
2603 gint id;
2604 GtkFileSelection * file_selector =
2605 (GtkFileSelection *)gtk_file_selection_new("Select a module");
2606 gtk_file_selection_set_filename(file_selector, load_module_path_alter);
2607 gtk_file_selection_hide_fileop_buttons(file_selector);
2608
2609 str[0] = '\0';
2610 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2611 switch(id){
2612 case GTK_RESPONSE_ACCEPT:
2613 case GTK_RESPONSE_OK:
2614 dir = gtk_file_selection_get_selections (file_selector);
2615 strncpy(str,dir[0],PATH_MAX);
2616 strncpy(remember_plugins_dir,dir[0],PATH_MAX);
2617 /* only keep file name */
2618 gchar *str1;
2619 str1 = strrchr(str,'/');
2620 if(str1)str1++;
2621 else{
2622 str1 = strrchr(str,'\\');
2623 str1++;
2624 }
2625#if 0
2626 /* remove "lib" */
2627 if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
2628 str1=str1+3;
2629 remove info after . */
2630 {
2631 gchar *str2 = str1;
2632
2633 str2 = strrchr(str2, '.');
2634 if(str2 != NULL) *str2 = '\0';
2635 }
2636 lttv_module_require(str1, &error);
2637#endif //0
2638 lttv_library_load(str1, &error);
2639 if(error != NULL) g_warning(error->message);
2640 else g_printf("Load library: %s\n", str);
2641 g_strfreev(dir);
2642 case GTK_RESPONSE_REJECT:
2643 case GTK_RESPONSE_CANCEL:
2644 default:
2645 gtk_widget_destroy((GtkWidget*)file_selector);
2646 break;
2647 }
2648
2649 }
2650
2651
2652
2653}
2654
2655
2656/* Display all loaded modules, let user to select a module to unload
2657 * by calling lttv_module_unload
2658 */
2659
2660void
2661on_unload_library_activate (GtkMenuItem *menuitem,
2662 gpointer user_data)
2663{
2664 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2665
2666 LttvLibrary *library;
2667 {
2668 GPtrArray *name;
2669 guint nb,i;
2670 gchar *lib_name;
2671 name = g_ptr_array_new();
2672 nb = lttv_library_number();
2673 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2674 /* ask for the library name */
2675
2676 for(i=0;i<nb;i++){
2677 LttvLibrary *iter_lib = lttv_library_get(i);
2678 lttv_library_info(iter_lib, &lib_info[i]);
2679
2680 gchar *path = lib_info[i].name;
2681 g_ptr_array_add(name, lib_info[i].name);
2682 }
2683 lib_name = get_selection((char **)(name->pdata), name->len,
2684 "Select a library", "Libraries");
2685 if(lib_name != NULL) {
2686 for(i=0;i<nb;i++){
2687 if(strcmp(lib_name, lib_info[i].name) == 0) {
2688 library = lttv_library_get(i);
2689 break;
2690 }
2691 }
2692 }
2693 g_ptr_array_free(name, TRUE);
2694 g_free(lib_info);
2695
2696 if(lib_name == NULL) return;
2697 }
2698
2699 lttv_library_unload(library);
2700}
2701
2702
abe346a3 2703/* Dispaly a file selection dialogue to let user select a module, then call
b052368a 2704 * lttv_module_require().
abe346a3 2705 */
2706
561eba2a 2707void
2708on_load_module_activate (GtkMenuItem *menuitem,
2709 gpointer user_data)
2710{
b052368a 2711 GError *error = NULL;
bca3b81f 2712 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
b052368a 2713
2714 LttvLibrary *library;
2715 {
2716 GPtrArray *name;
2717 guint nb,i;
2718 gchar *lib_name;
2719 name = g_ptr_array_new();
2720 nb = lttv_library_number();
2721 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2722 /* ask for the library name */
2723
2724 for(i=0;i<nb;i++){
2725 LttvLibrary *iter_lib = lttv_library_get(i);
2726 lttv_library_info(iter_lib, &lib_info[i]);
2727
2728 gchar *path = lib_info[i].name;
2729 g_ptr_array_add(name, path);
2730 }
2731 lib_name = get_selection((char **)(name->pdata), name->len,
2732 "Select a library", "Libraries");
2733 if(lib_name != NULL) {
2734 for(i=0;i<nb;i++){
2735 if(strcmp(lib_name, lib_info[i].name) == 0) {
2736 library = lttv_library_get(i);
2737 break;
2738 }
3872a20e 2739 }
b052368a 2740 }
2741 g_ptr_array_free(name, TRUE);
2742 g_free(lib_info);
2743
2744 if(lib_name == NULL) return;
36b3c068 2745 }
b052368a 2746
2747 //LttvModule *module;
2748 gchar module_name_out[PATH_MAX];
2749 {
2750 /* Ask for the module to load : list modules in the selected lib */
2751 GPtrArray *name;
2752 guint nb,i;
2753 gchar *module_name;
2754 LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
2755 name = g_ptr_array_new();
2756 nb = lttv_library_module_number(library);
2757 /* ask for the module name */
2758
2759 for(i=0;i<nb;i++){
2760 LttvModule *iter_module = lttv_library_module_get(library, i);
2761 lttv_module_info(iter_module, &module_info[i]);
2762
2763 gchar *path = module_info[i].name;
2764 g_ptr_array_add(name, path);
2765 }
2766 module_name = get_selection((char **)(name->pdata), name->len,
2767 "Select a module", "Modules");
2768 if(module_name != NULL) {
2769 for(i=0;i<nb;i++){
2770 if(strcmp(module_name, module_info[i].name) == 0) {
2771 strncpy(module_name_out, module_name, PATH_MAX);
2772 //module = lttv_library_module_get(i);
2773 break;
2774 }
2775 }
2776 }
2777
2778 g_ptr_array_free(name, TRUE);
2779 g_free(module_info);
2780
2781 if(module_name == NULL) return;
2782 }
2783
2784 lttv_module_require(module_name_out, &error);
2785 if(error != NULL) g_warning(error->message);
2786 else g_printf("Load module: %s\n", module_name_out);
2787
2788
2789#if 0
2790 {
2791
2792
2793 gchar str[PATH_MAX];
2794 gchar ** dir;
2795 gint id;
2796 GtkFileSelection * file_selector =
2797 (GtkFileSelection *)gtk_file_selection_new("Select a module");
2798 gtk_file_selection_set_filename(file_selector, load_module_path_alter);
2799 gtk_file_selection_hide_fileop_buttons(file_selector);
2800
2801 str[0] = '\0';
2802 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2803 switch(id){
2804 case GTK_RESPONSE_ACCEPT:
2805 case GTK_RESPONSE_OK:
2806 dir = gtk_file_selection_get_selections (file_selector);
2807 strncpy(str,dir[0],PATH_MAX);
2808 strncpy(remember_plugins_dir,dir[0],PATH_MAX);
2809 {
2810 /* only keep file name */
2811 gchar *str1;
2812 str1 = strrchr(str,'/');
2813 if(str1)str1++;
2814 else{
2815 str1 = strrchr(str,'\\');
2816 str1++;
2817 }
2818#if 0
2819 /* remove "lib" */
2820 if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
2821 str1=str1+3;
2822 remove info after . */
2823 {
2824 gchar *str2 = str1;
2825
2826 str2 = strrchr(str2, '.');
2827 if(str2 != NULL) *str2 = '\0';
2828 }
2829 lttv_module_require(str1, &error);
2830#endif //0
2831 lttv_library_load(str1, &error);
2832 if(error != NULL) g_warning(error->message);
2833 else g_printf("Load library: %s\n", str);
2834 g_strfreev(dir);
2835 case GTK_RESPONSE_REJECT:
2836 case GTK_RESPONSE_CANCEL:
2837 default:
2838 gtk_widget_destroy((GtkWidget*)file_selector);
2839 break;
2840 }
2841
2842 }
2843#endif //0
2844
2845
561eba2a 2846}
2847
2848
b052368a 2849
abe346a3 2850/* Display all loaded modules, let user to select a module to unload
2851 * by calling lttv_module_unload
2852 */
2853
561eba2a 2854void
2855on_unload_module_activate (GtkMenuItem *menuitem,
2856 gpointer user_data)
2857{
b052368a 2858 GError *error = NULL;
bca3b81f 2859 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
08b1c66e 2860
b052368a 2861 LttvLibrary *library;
2862 {
2863 GPtrArray *name;
2864 guint nb,i;
2865 gchar *lib_name;
2866 name = g_ptr_array_new();
2867 nb = lttv_library_number();
2868 LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
2869 /* ask for the library name */
36b3c068 2870
36b3c068 2871 for(i=0;i<nb;i++){
b052368a 2872 LttvLibrary *iter_lib = lttv_library_get(i);
2873 lttv_library_info(iter_lib, &lib_info[i]);
2874
2875 gchar *path = lib_info[i].name;
2876 g_ptr_array_add(name, path);
2877 }
2878 lib_name = get_selection((char **)(name->pdata), name->len,
2879 "Select a library", "Libraries");
2880 if(lib_name != NULL) {
2881 for(i=0;i<nb;i++){
2882 if(strcmp(lib_name, lib_info[i].name) == 0) {
2883 library = lttv_library_get(i);
2884 break;
2885 }
36b3c068 2886 }
b052368a 2887 }
2888 g_ptr_array_free(name, TRUE);
2889 g_free(lib_info);
2890
2891 if(lib_name == NULL) return;
36b3c068 2892 }
2893
b052368a 2894 LttvModule *module;
2895 {
2896 /* Ask for the module to load : list modules in the selected lib */
2897 GPtrArray *name;
2898 guint nb,i;
2899 gchar *module_name;
6d677a86 2900 nb = lttv_library_module_number(library);
b052368a 2901 LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
2902 name = g_ptr_array_new();
b052368a 2903 /* ask for the module name */
2904
2905 for(i=0;i<nb;i++){
2906 LttvModule *iter_module = lttv_library_module_get(library, i);
2907 lttv_module_info(iter_module, &module_info[i]);
2908
2909 gchar *path = module_info[i].name;
2910 if(module_info[i].use_count > 0) g_ptr_array_add(name, path);
2911 }
2912 module_name = get_selection((char **)(name->pdata), name->len,
2913 "Select a module", "Modules");
2914 if(module_name != NULL) {
2915 for(i=0;i<nb;i++){
2916 if(strcmp(module_name, module_info[i].name) == 0) {
2917 module = lttv_library_module_get(library, i);
2918 break;
2919 }
2920 }
2921 }
2922
2923 g_ptr_array_free(name, TRUE);
2924 g_free(module_info);
2925
2926 if(module_name == NULL) return;
2927 }
2928
b052368a 2929 LttvModuleInfo module_info;
2930 lttv_module_info(module, &module_info);
2931 g_printf("Release module: %s\n", module_info.name);
fce9a2fc 2932
2933 lttv_module_release(module);
561eba2a 2934}
2935
2936
b052368a 2937/* Display a directory dialogue to let user select a path for library searching
abe346a3 2938 */
2939
561eba2a 2940void
b052368a 2941on_add_library_search_path_activate (GtkMenuItem *menuitem,
561eba2a 2942 gpointer user_data)
2943{
b052368a 2944 GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
67b98724 2945 const char * dir;
fc188b78 2946 gint id;
2947
bca3b81f 2948 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
3658a338 2949 if(remember_plugins_dir[0] != '\0')
2950 gtk_dir_selection_set_filename(file_selector, remember_plugins_dir);
fc188b78 2951
68b48a45 2952 id = gtk_dialog_run(GTK_DIALOG(file_selector));
fc188b78 2953 switch(id){
2954 case GTK_RESPONSE_ACCEPT:
2955 case GTK_RESPONSE_OK:
68b48a45 2956 dir = gtk_dir_selection_get_dir (file_selector);
a1a2b649 2957 strncpy(remember_plugins_dir,dir,PATH_MAX);
2958 strncat(remember_plugins_dir,"/",PATH_MAX);
08b1c66e 2959 lttv_library_path_add(dir);
fc188b78 2960 case GTK_RESPONSE_REJECT:
2961 case GTK_RESPONSE_CANCEL:
2962 default:
68b48a45 2963 gtk_widget_destroy((GtkWidget*)file_selector);
fc188b78 2964 break;
6b1d3120 2965 }
561eba2a 2966}
2967
2968
b052368a 2969/* Display a directory dialogue to let user select a path for library searching
2970 */
2971
2972void
2973on_remove_library_search_path_activate (GtkMenuItem *menuitem,
2974 gpointer user_data)
2975{
2976 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2977
2978 const char *lib_path;
2979 {
2980 GPtrArray *name;
2981 guint nb,i;
2982 gchar *lib_name;
2983 name = g_ptr_array_new();
2984 nb = lttv_library_path_number();
2985 /* ask for the library name */
2986
2987 for(i=0;i<nb;i++){
2988 gchar *path = lttv_library_path_get(i);
2989 g_ptr_array_add(name, path);
2990 }
2991 lib_path = get_selection((char **)(name->pdata), name->len,
2992 "Select a library path", "Library paths");
2993
2994 g_ptr_array_free(name, TRUE);
2995
2996 if(lib_path == NULL) return;
2997 }
2998
2999 lttv_library_path_remove(lib_path);
3000}
3001
561eba2a 3002void
3003on_color_activate (GtkMenuItem *menuitem,
3004 gpointer user_data)
3005{
3006 g_printf("Color\n");
3007}
3008
3009
3010void
3011on_filter_activate (GtkMenuItem *menuitem,
3012 gpointer user_data)
3013{
3014 g_printf("Filter\n");
3015}
3016
3017
3018void
3019on_save_configuration_activate (GtkMenuItem *menuitem,
3020 gpointer user_data)
3021{
3022 g_printf("Save configuration\n");
3023}
3024
3025
3026void
3027on_content_activate (GtkMenuItem *menuitem,
3028 gpointer user_data)
3029{
3030 g_printf("Content\n");
3031}
3032
3033
51ef553b 3034static void
3035on_about_close_activate (GtkButton *button,
3036 gpointer user_data)
3037{
3038 GtkWidget *about_widget = GTK_WIDGET(user_data);
3039
3040 gtk_widget_destroy(about_widget);
3041}
3042
561eba2a 3043void
3044on_about_activate (GtkMenuItem *menuitem,
3045 gpointer user_data)
3046{
51ef553b 3047 MainWindow *main_window = get_window_data_struct(GTK_WIDGET(menuitem));
3048 GtkWidget *window_widget = main_window->mwindow;
3049 GtkWidget *about_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
3050 GtkWindow *about_window = GTK_WINDOW(about_widget);
3051 gint window_width, window_height;
3052
3053 gtk_window_set_title(about_window, "About Linux Trace Toolkit");
3054
3055 gtk_window_set_resizable(about_window, FALSE);
3056 gtk_window_set_transient_for(GTK_WINDOW(window_widget), about_window);
3057 gtk_window_set_destroy_with_parent(about_window, TRUE);
3058 gtk_window_set_modal(about_window, FALSE);
3059
3060 /* Put the about window at the center of the screen */
3061 gtk_window_get_size(about_window, &window_width, &window_height);
3062 gtk_window_move (about_window,
3063 (gdk_screen_width() - window_width)/2,
3064 (gdk_screen_height() - window_height)/2);
3065
3066 GtkWidget *vbox = gtk_vbox_new(FALSE, 1);
3067
3068 gtk_container_add(GTK_CONTAINER(about_widget), vbox);
3069
3070
3071 /* Text to show */
3072 GtkWidget *label1 = gtk_label_new("");
c8bba5fa 3073 gtk_misc_set_padding(GTK_MISC(label1), 10, 20);
51ef553b 3074 gtk_label_set_markup(GTK_LABEL(label1), "\
c8bba5fa 3075<big>Linux Trace Toolkit</big>");
51ef553b 3076 gtk_label_set_justify(GTK_LABEL(label1), GTK_JUSTIFY_CENTER);
3077
3078 GtkWidget *label2 = gtk_label_new("");
c8bba5fa 3079 gtk_misc_set_padding(GTK_MISC(label2), 10, 20);
51ef553b 3080 gtk_label_set_markup(GTK_LABEL(label2), "\
51ef553b 3081Project author: Karim Yaghmour\n\
3082\n\
3083Contributors :\n\
3084\n\
3085Michel Dagenais (New trace format, lttv main)\n\
3086Mathieu Desnoyers (Directory structure, build with automake/conf,\n\
c8bba5fa 3087 lttv gui, control flow view, gui green threads\n\
3088 with interruptible foreground and background computation,\n\
3089 detailed event list)\n\
51ef553b 3090Benoit Des Ligneris (Cluster adaptation)\n\
3091Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
3092 detailed event list and statistics view)\n\
3093Tom Zanussi (RelayFS)");
c8bba5fa 3094
3095 GtkWidget *label3 = gtk_label_new("");
3096 gtk_label_set_markup(GTK_LABEL(label3), "\
3097Linux Trace Toolkit, Copyright (C) 2004 Karim Yaghmour\n\
3098Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
3099This is free software, and you are welcome to redistribute it\n\
3100under certain conditions. See COPYING for details.");
3101 gtk_misc_set_padding(GTK_MISC(label3), 10, 20);
3102
51ef553b 3103 gtk_box_pack_start_defaults(GTK_BOX(vbox), label1);
3104 gtk_box_pack_start_defaults(GTK_BOX(vbox), label2);
c8bba5fa 3105 gtk_box_pack_start_defaults(GTK_BOX(vbox), label3);
51ef553b 3106
3107 GtkWidget *hbox = gtk_hbox_new(TRUE, 0);
3108 gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
3109 GtkWidget *close_button = gtk_button_new_with_mnemonic("_Close");
3110 gtk_box_pack_end(GTK_BOX(hbox), close_button, FALSE, FALSE, 0);
3111 gtk_container_set_border_width(GTK_CONTAINER(close_button), 20);
3112
3113 g_signal_connect(G_OBJECT(close_button), "clicked",
3114 G_CALLBACK(on_about_close_activate),
3115 (gpointer)about_widget);
3116
3117 gtk_widget_show_all(about_widget);
561eba2a 3118}
3119
3120
3121void
3122on_button_new_clicked (GtkButton *button,
3123 gpointer user_data)
3124{
6f7ad7ae 3125 create_new_window((GtkWidget*)button, user_data, TRUE);
561eba2a 3126}
3127
2901f314 3128void
3129on_button_new_tab_clicked (GtkButton *button,
3130 gpointer user_data)
3131{
3132 create_new_tab((GtkWidget*)button, user_data);
3133}
561eba2a 3134
3135void
3136on_button_open_clicked (GtkButton *button,
3137 gpointer user_data)
3138{
3139 open_traceset((GtkWidget*)button, user_data);
3140}
3141
3142
3143void
3144on_button_add_trace_clicked (GtkButton *button,
3145 gpointer user_data)
3146{
3147 add_trace((GtkWidget*)button, user_data);
3148}
3149
3150
3151void
3152on_button_remove_trace_clicked (GtkButton *button,
3153 gpointer user_data)
3154{
3155 remove_trace((GtkWidget*)button, user_data);
3156}
3157
9878c8a4 3158void
3159on_button_redraw_clicked (GtkButton *button,
3160 gpointer user_data)
3161{
3162 redraw((GtkWidget*)button, user_data);
3163}
3164
3165void
3166on_button_continue_processing_clicked (GtkButton *button,
3167 gpointer user_data)
3168{
3169 continue_processing((GtkWidget*)button, user_data);
3170}
3171
3172void
3173on_button_stop_processing_clicked (GtkButton *button,
3174 gpointer user_data)
3175{
3176 stop_processing((GtkWidget*)button, user_data);
3177}
3178
3179
561eba2a 3180
3181void
3182on_button_save_clicked (GtkButton *button,
3183 gpointer user_data)
3184{
3185 save((GtkWidget*)button, user_data);
3186}
3187
3188
3189void
3190on_button_save_as_clicked (GtkButton *button,
3191 gpointer user_data)
3192{
3193 save_as((GtkWidget*)button, user_data);
3194}
3195
3196
3197void
3198on_button_zoom_in_clicked (GtkButton *button,
3199 gpointer user_data)
3200{
3201 zoom_in((GtkWidget*)button, user_data);
3202}
3203
3204
3205void
3206on_button_zoom_out_clicked (GtkButton *button,
3207 gpointer user_data)
3208{
3209 zoom_out((GtkWidget*)button, user_data);
3210}
3211
3212
3213void
3214on_button_zoom_extended_clicked (GtkButton *button,
3215 gpointer user_data)
3216{
3217 zoom_extended((GtkWidget*)button, user_data);
3218}
3219
3220
3221void
3222on_button_go_to_time_clicked (GtkButton *button,
3223 gpointer user_data)
3224{
3225 go_to_time((GtkWidget*)button, user_data);
3226}
3227
3228
3229void
3230on_button_show_time_frame_clicked (GtkButton *button,
3231 gpointer user_data)
3232{
3233 show_time_frame((GtkWidget*)button, user_data);
3234}
3235
3236
3237void
3238on_button_move_up_clicked (GtkButton *button,
3239 gpointer user_data)
3240{
3241 move_up_viewer((GtkWidget*)button, user_data);
3242}
3243
3244
3245void
3246on_button_move_down_clicked (GtkButton *button,
3247 gpointer user_data)
3248{
3249 move_down_viewer((GtkWidget*)button, user_data);
3250}
3251
3252
3253void
3254on_button_delete_viewer_clicked (GtkButton *button,
3255 gpointer user_data)
3256{
3257 delete_viewer((GtkWidget*)button, user_data);
3258}
3259
3260void
2d262115 3261on_MWindow_destroy (GtkWidget *widget,
561eba2a 3262 gpointer user_data)
3263{
2d262115 3264 MainWindow *main_window = get_window_data_struct(widget);
ef68c3ac 3265 LttvIAttribute *attributes = main_window->attributes;
3266 LttvAttributeValue value;
e4d09234 3267
ef68c3ac 3268 //This is unnecessary, since widgets will be destroyed
3269 //by the main window widget anyway.
3270 //remove_all_menu_toolbar_constructors(main_window, NULL);
3271
3272 g_assert(lttv_iattribute_find_by_path(attributes,
3273 "viewers/menu", LTTV_POINTER, &value));
3274 lttv_menus_destroy((LttvMenus*)*(value.v_pointer));
3275
501e4e70 3276 g_assert(lttv_iattribute_find_by_path(attributes,
ef68c3ac 3277 "viewers/toolbar", LTTV_POINTER, &value));
3278 lttv_toolbars_destroy((LttvToolbars*)*(value.v_pointer));
2d262115 3279
ef68c3ac 3280 g_object_unref(main_window->attributes);
3281 g_main_window_list = g_slist_remove(g_main_window_list, main_window);
561eba2a 3282
ef68c3ac 3283 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list));
2d262115 3284 if(g_slist_length(g_main_window_list) == 0)
7a859036 3285 gtk_main_quit ();
561eba2a 3286}
3287
58eecf4a 3288gboolean
3289on_MWindow_configure (GtkWidget *widget,
3290 GdkEventConfigure *event,
3291 gpointer user_data)
3292{
3293 MainWindow * mw_data = get_window_data_struct((GtkWidget*)widget);
3294 float width = event->width;
58eecf4a 3295 TimeWindow time_win;
3296 double ratio;
3297 TimeInterval *time_span;
3298 LttTime time;
bd24a9af 3299
3300 // MD : removed time width modification upon resizing of the main window.
3301 // The viewers will redraw themselves completely, without time interval
3302 // modification.
3303/* while(tab){
58eecf4a 3304 if(mw_data->window_width){
3305 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
3306 time_win = tab->time_window;
3307 ratio = width / mw_data->window_width;
3308 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
3309 time = ltt_time_sub(time_span->endTime, time_win.start_time);
3310 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
3311 tab->time_window.time_width = time;
3312 }
3313 }
3314 tab = tab->next;
3315 }
3316
3317 mw_data->window_width = (int)width;
bd24a9af 3318 */
58eecf4a 3319 return FALSE;
3320}
561eba2a 3321
abe346a3 3322/* Set current tab
3323 */
3324
561eba2a 3325void
3326on_MNotebook_switch_page (GtkNotebook *notebook,
3327 GtkNotebookPage *page,
3328 guint page_num,
3329 gpointer user_data)
3330{
47cd8a09 3331
561eba2a 3332}
3333
abe346a3 3334
e800cf84 3335void time_change_manager (Tab *tab,
3336 TimeWindow new_time_window)
3337{
3338 /* Only one source of time change */
3339 if(tab->time_manager_lock == TRUE) return;
3340
3341 tab->time_manager_lock = TRUE;
3342
3343 LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3344 TimeInterval time_span = tsc->time_span;
3345 LttTime start_time = new_time_window.start_time;
3346 LttTime end_time = ltt_time_add(new_time_window.start_time,
3347 new_time_window.time_width);
3348
3349 /* Set scrollbar */
3350 GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(tab->scrollbar));
3351 LttTime upper = ltt_time_sub(time_span.end_time, time_span.start_time);
3352#if 0
3353 gtk_range_set_increments(GTK_RANGE(tab->scrollbar),
3354 ltt_time_to_double(new_time_window.time_width)
3355 / SCROLL_STEP_PER_PAGE
3356 * NANOSECONDS_PER_SECOND, /* step increment */
3357 ltt_time_to_double(new_time_window.time_width)
3358 * NANOSECONDS_PER_SECOND); /* page increment */
3359 gtk_range_set_range(GTK_RANGE(tab->scrollbar),
3360 0.0, /* lower */
3361 ltt_time_to_double(upper)
3362 * NANOSECONDS_PER_SECOND); /* upper */
3363#endif //0
3364 g_object_set(G_OBJECT(adjustment),
3365 "lower",
3366 0.0, /* lower */
3367 "upper",
3368 ltt_time_to_double(upper)
3369 * NANOSECONDS_PER_SECOND, /* upper */
3370 "step_increment",
3371 ltt_time_to_double(new_time_window.time_width)
3372 / SCROLL_STEP_PER_PAGE
3373 * NANOSECONDS_PER_SECOND, /* step increment */
3374 "page_increment",
3375 ltt_time_to_double(new_time_window.time_width)
3376 * NANOSECONDS_PER_SECOND, /* page increment */
3377 "page_size",
3378 ltt_time_to_double(new_time_window.time_width)
3379 * NANOSECONDS_PER_SECOND, /* page size */
3380 NULL);
3381 gtk_adjustment_changed(adjustment);
3382
3383 // g_object_set(G_OBJECT(adjustment),
3384 // "value",
3385 // ltt_time_to_double(
3386 // ltt_time_sub(start_time, time_span.start_time))
3387 // * NANOSECONDS_PER_SECOND, /* value */
3388 // NULL);
3389 //gtk_adjustment_value_changed(adjustment);
3390 gtk_range_set_value(GTK_RANGE(tab->scrollbar),
3391 ltt_time_to_double(
3392 ltt_time_sub(start_time, time_span.start_time))
3393 * NANOSECONDS_PER_SECOND /* value */);
3394
3395 /* set the time bar. */
3396 /* start seconds */
3397 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry1),
3398 (double)time_span.start_time.tv_sec,
3399 (double)time_span.end_time.tv_sec);
3400 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry1),
3401 (double)start_time.tv_sec);
3402
3403 /* start nanoseconds */
3404 if(start_time.tv_sec == time_span.start_time.tv_sec) {
71624cb7 3405 /* can be both beginning and end at the same time. */
3406 if(start_time.tv_sec == time_span.end_time.tv_sec) {
3407 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3408 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
3409 (double)time_span.start_time.tv_nsec,
3410 (double)time_span.end_time.tv_nsec-1);
3411 } else {
3412 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
3413 (double)time_span.start_time.tv_nsec,
3414 (double)NANOSECONDS_PER_SECOND-1);
3415 }
3416 } else if(start_time.tv_sec == time_span.end_time.tv_sec) {
3417 /* If we are at the end, max nsec to end.. -1 (not zero length) */
3418 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
3419 0.0,
3420 (double)time_span.end_time.tv_nsec-1);
3421 } else /* anywhere else */
e800cf84 3422 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
3423 0.0,
3424 (double)NANOSECONDS_PER_SECOND-1);
3425 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry2),
3426 (double)start_time.tv_nsec);
3427
3428 /* end seconds */
3429 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry3),
3430 (double)time_span.start_time.tv_sec,
3431 (double)time_span.end_time.tv_sec);
3432 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry3),
3433 (double)end_time.tv_sec);
3434
3435 /* end nanoseconds */
3436 if(end_time.tv_sec == time_span.start_time.tv_sec) {
71624cb7 3437 /* can be both beginning and end at the same time. */
3438 if(end_time.tv_sec == time_span.end_time.tv_sec) {
3439 /* If we are at the end, max nsec to end.. */
3440 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
3441 (double)time_span.start_time.tv_nsec+1,
3442 (double)time_span.end_time.tv_nsec);
3443 } else {
3444 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
3445 (double)time_span.start_time.tv_nsec+1,
3446 (double)NANOSECONDS_PER_SECOND-1);
3447 }
e800cf84 3448 }
3449 else if(end_time.tv_sec == time_span.end_time.tv_sec) {
3450 /* If we are at the end, max nsec to end.. */
3451 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
3452 0.0,
3453 (double)time_span.end_time.tv_nsec);
3454 }
3455 else /* anywhere else */
3456 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
3457 0.0,
3458 (double)NANOSECONDS_PER_SECOND-1);
3459 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry4),
3460 (double)end_time.tv_nsec);
3461
3462 /* call viewer hooks for new time window */
3463 set_time_window(tab, &new_time_window);
3464
3465 tab->time_manager_lock = FALSE;
3466}
3467
3468
3469/* value changed for frame start s
3470 *
3471 * Check time span : if ns is out of range, clip it the nearest good value.
3472 */
3473void
3474on_MEntry1_value_changed (GtkSpinButton *spinbutton,
3475 gpointer user_data)
3476{
3477 Tab *tab =(Tab *)user_data;
3478 LttvTracesetContext * tsc =
3479 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3480 TimeInterval time_span = tsc->time_span;
3481 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3482
3483 TimeWindow new_time_window = tab->time_window;
3484
3485 LttTime end_time = ltt_time_add(new_time_window.start_time,
3486 new_time_window.time_width);
3487
3488 new_time_window.start_time.tv_sec = value;
3489
3490 /* start nanoseconds */
3491 if(new_time_window.start_time.tv_sec == time_span.start_time.tv_sec) {
71624cb7 3492 if(new_time_window.start_time.tv_sec == time_span.end_time.tv_sec) {
3493 if(new_time_window.start_time.tv_nsec > time_span.end_time.tv_nsec)
3494 new_time_window.start_time.tv_nsec = time_span.end_time.tv_nsec-1;
3495 if(new_time_window.start_time.tv_nsec < time_span.start_time.tv_nsec)
3496 new_time_window.start_time.tv_nsec = time_span.start_time.tv_nsec;
3497 } else {
3498 if(new_time_window.start_time.tv_nsec < time_span.start_time.tv_nsec)
3499 new_time_window.start_time.tv_nsec = time_span.start_time.tv_nsec;
3500 }
e800cf84 3501 }
3502 else if(new_time_window.start_time.tv_sec == time_span.end_time.tv_sec) {
3503 if(new_time_window.start_time.tv_nsec > time_span.end_time.tv_nsec)
3504 new_time_window.start_time.tv_nsec = time_span.end_time.tv_nsec-1;
3505 }
3506
3507 /* check if end time selected is below or equal */
3508 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3509 /* Then, we must push back end time : keep the same time width
3510 * if possible, else end traceset time */
3511 end_time = LTT_TIME_MIN(time_span.end_time,
3512 ltt_time_add(new_time_window.start_time,
3513 new_time_window.time_width)
3514 );
3515 }
3516
3517 /* Fix the time width to fit start time and end time */
3518 new_time_window.time_width = ltt_time_sub(end_time,
3519 new_time_window.start_time);
3520
3521 time_change_manager(tab, new_time_window);
3522
3523}
3524
3525void
3526on_MEntry2_value_changed (GtkSpinButton *spinbutton,
3527 gpointer user_data)
3528{
3529 Tab *tab =(Tab *)user_data;
3530 LttvTracesetContext * tsc =
3531 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3532 TimeInterval time_span = tsc->time_span;
3533 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3534
3535 TimeWindow new_time_window = tab->time_window;
3536
3537 LttTime end_time = ltt_time_add(new_time_window.start_time,
3538 new_time_window.time_width);
3539
3540 new_time_window.start_time.tv_nsec = value;
3541
3542 /* check if end time selected is below or equal */
3543 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3544 /* Then, we must push back end time : keep the same time width
3545 * if possible, else end traceset time */
3546 end_time = LTT_TIME_MIN(time_span.end_time,
3547 ltt_time_add(new_time_window.start_time,
3548 new_time_window.time_width)
3549 );
3550 }
3551
3552 /* Fix the time width to fit start time and end time */
3553 new_time_window.time_width = ltt_time_sub(end_time,
3554 new_time_window.start_time);
3555
3556 time_change_manager(tab, new_time_window);
3557
3558}
3559
3560void
3561on_MEntry3_value_changed (GtkSpinButton *spinbutton,
3562 gpointer user_data)
3563{
3564 Tab *tab =(Tab *)user_data;
3565 LttvTracesetContext * tsc =
3566 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3567 TimeInterval time_span = tsc->time_span;
3568 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3569
3570 TimeWindow new_time_window = tab->time_window;
3571
3572 LttTime end_time = ltt_time_add(new_time_window.start_time,
3573 new_time_window.time_width);
3574 end_time.tv_sec = value;
3575
3576 /* end nanoseconds */
3577 if(end_time.tv_sec == time_span.start_time.tv_sec) {
71624cb7 3578 if(end_time.tv_sec == time_span.end_time.tv_sec) {
3579 if(end_time.tv_nsec > time_span.end_time.tv_nsec)
3580 end_time.tv_nsec = time_span.end_time.tv_nsec;
3581 if(end_time.tv_nsec < time_span.start_time.tv_nsec)
3582 end_time.tv_nsec = time_span.start_time.tv_nsec+1;
3583 } else {
3584 if(end_time.tv_nsec < time_span.start_time.tv_nsec)
3585 end_time.tv_nsec = time_span.start_time.tv_nsec+1;
3586 }
e800cf84 3587 }
3588 else if(end_time.tv_sec == time_span.end_time.tv_sec) {
3589 if(end_time.tv_nsec > time_span.end_time.tv_nsec)
3590 end_time.tv_nsec = time_span.end_time.tv_nsec;
3591 }
3592
3593 /* check if end time selected is below or equal */
3594 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3595 /* Then, we must push front start time : keep the same time width
3596 * if possible, else end traceset time */
3597 new_time_window.start_time = LTT_TIME_MAX(time_span.start_time,
3598 ltt_time_sub(end_time,
3599 new_time_window.time_width)
3600 );
3601 }
3602
3603 /* Fix the time width to fit start time and end time */
3604 new_time_window.time_width = ltt_time_sub(end_time,
3605 new_time_window.start_time);
3606
3607 time_change_manager(tab, new_time_window);
3608
3609}
3610
3611void
3612on_MEntry4_value_changed (GtkSpinButton *spinbutton,
3613 gpointer user_data)
3614{
3615 Tab *tab =(Tab *)user_data;
3616 LttvTracesetContext * tsc =
3617 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3618 TimeInterval time_span = tsc->time_span;
3619 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3620
3621 TimeWindow new_time_window = tab->time_window;
3622
3623 LttTime end_time = ltt_time_add(new_time_window.start_time,
3624 new_time_window.time_width);
3625 end_time.tv_nsec = value;
3626
3627 /* check if end time selected is below or equal */
3628 if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
3629 /* Then, we must push front start time : keep the same time width
3630 * if possible, else end traceset time */
3631 new_time_window.start_time = LTT_TIME_MAX(time_span.start_time,
3632 ltt_time_sub(end_time,
3633 new_time_window.time_width)
3634 );
3635 }
3636
3637 /* Fix the time width to fit start time and end time */
3638 new_time_window.time_width = ltt_time_sub(end_time,
3639 new_time_window.start_time);
3640
3641 time_change_manager(tab, new_time_window);
3642
3643}
3644
3645
3646void current_time_change_manager (Tab *tab,
3647 LttTime new_current_time)
3648{
3649 /* Only one source of time change */
3650 if(tab->current_time_manager_lock == TRUE) return;
3651
3652 tab->current_time_manager_lock = TRUE;
3653
3654 LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3655 TimeInterval time_span = tsc->time_span;
3656
e800cf84 3657 /* current seconds */
3658 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry5),
3659 (double)time_span.start_time.tv_sec,
3660 (double)time_span.end_time.tv_sec);
db8bc917 3661 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry5),
3662 (double)new_current_time.tv_sec);
71624cb7 3663
3664
e800cf84 3665 /* start nanoseconds */
3666 if(new_current_time.tv_sec == time_span.start_time.tv_sec) {
71624cb7 3667 /* can be both beginning and end at the same time. */
3668 if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
3669 /* If we are at the end, max nsec to end.. */
3670 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
3671 (double)time_span.start_time.tv_nsec,
3672 (double)time_span.end_time.tv_nsec);
3673 } else {
3674 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
3675 (double)time_span.start_time.tv_nsec,
3676 (double)NANOSECONDS_PER_SECOND-1);
3677 }
3678 } else if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
3679 /* If we are at the end, max nsec to end.. */
3680 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
3681 0.0,
3682 (double)time_span.end_time.tv_nsec);
3683 } else /* anywhere else */
e800cf84 3684 gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
3685 0.0,
3686 (double)NANOSECONDS_PER_SECOND-1);
71624cb7 3687
e800cf84 3688 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry6),
3689 (double)new_current_time.tv_nsec);
3690
db8bc917 3691 set_current_time(tab, &new_current_time);
e800cf84 3692
3693 tab->current_time_manager_lock = FALSE;
3694}
3695
3696void
3697on_MEntry5_value_changed (GtkSpinButton *spinbutton,
3698 gpointer user_data)
3699{
3700 Tab *tab = (Tab*)user_data;
3701 LttvTracesetContext * tsc =
3702 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
3703 TimeInterval time_span = tsc->time_span;
3704 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3705 LttTime new_current_time = tab->current_time;
3706 new_current_time.tv_sec = value;
3707
3708 /* current nanoseconds */
3709 if(new_current_time.tv_sec == time_span.start_time.tv_sec) {
71624cb7 3710 if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
3711 if(new_current_time.tv_nsec > time_span.end_time.tv_nsec)
3712 new_current_time.tv_nsec = time_span.end_time.tv_nsec;
3713 if(new_current_time.tv_nsec < time_span.start_time.tv_nsec)
3714 new_current_time.tv_nsec = time_span.start_time.tv_nsec;
3715 } else {
3716 if(new_current_time.tv_nsec < time_span.start_time.tv_nsec)
3717 new_current_time.tv_nsec = time_span.start_time.tv_nsec;
3718 }
e800cf84 3719 }
3720 else if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
3721 if(new_current_time.tv_nsec > time_span.end_time.tv_nsec)
3722 new_current_time.tv_nsec = time_span.end_time.tv_nsec;
3723 }
3724
3725 current_time_change_manager(tab, new_current_time);
3726}
3727
3728void
3729on_MEntry6_value_changed (GtkSpinButton *spinbutton,
3730 gpointer user_data)
3731{
3732 Tab *tab = (Tab*)user_data;
3733 gint value = gtk_spin_button_get_value_as_int(spinbutton);
3734 LttTime new_current_time = tab->current_time;
3735 new_current_time.tv_nsec = value;
3736
3737 current_time_change_manager(tab, new_current_time);
3738}
3739
3740
b052368a 3741void scroll_value_changed_cb(GtkWidget *scrollbar,
3742 gpointer user_data)
3743{
3744 Tab *tab = (Tab *)user_data;
e800cf84 3745 TimeWindow new_time_window;
b052368a 3746 LttTime time;
3747 GtkAdjustment *adjust = gtk_range_get_adjustment(GTK_RANGE(scrollbar));
3748 gdouble value = gtk_adjustment_get_value(adjust);
e800cf84 3749 // gdouble upper, lower, ratio, page_size;
3750 gdouble page_size;
b052368a 3751 LttvTracesetContext * tsc =
3752 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
b9a010a2 3753 TimeInterval time_span = tsc->time_span;
b052368a 3754
e800cf84 3755 time = ltt_time_add(ltt_time_from_double(value/NANOSECONDS_PER_SECOND),
3756 time_span.start_time);
3757
3758 new_time_window.start_time = time;
3759
3760 page_size = adjust->page_size;
3761
3762 new_time_window.time_width =
3763 ltt_time_from_double(page_size/NANOSECONDS_PER_SECOND);
3764
3765
3766 time_change_manager(tab, new_time_window);
3767#if 0
b052368a 3768 //time_window = tab->time_window;
3769
b052368a 3770 lower = adjust->lower;
3771 upper = adjust->upper;
3772 ratio = (value - lower) / (upper - lower);
2b5cc5a5 3773 g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower, upper, value, ratio);
b052368a 3774
3775 //time = ltt_time_sub(time_span->end_time, time_span->start_time);
3776 //time = ltt_time_mul(time, (float)ratio);
3777 //time = ltt_time_add(time_span->start_time, time);
b9a010a2 3778 time = ltt_time_add(ltt_time_from_double(value/NANOSECONDS_PER_SECOND),
3779 time_span.start_time);
b052368a 3780
3781 time_window.start_time = time;
3782
3783 page_size = adjust->page_size;
3784
3785 time_window.time_width =
3786 ltt_time_from_double(page_size/NANOSECONDS_PER_SECOND);
b9a010a2 3787 //time = ltt_time_sub(time_span.end_time, time);
b052368a 3788 //if(ltt_time_compare(time,time_window.time_width) < 0){
3789 // time_window.time_width = time;
3790 //}
3791
3792 /* call viewer hooks for new time window */
3793 set_time_window(tab, &time_window);
e800cf84 3794#endif //0
b052368a 3795}
3796
3797
abe346a3 3798/* callback function to check or uncheck the check box (filter)
3799 */
3800
49bf71b5 3801void checkbox_changed(GtkTreeView *treeview,
3802 GtkTreePath *arg1,
3803 GtkTreeViewColumn *arg2,
3804 gpointer user_data)
3805{
3806 GtkTreeStore * store = (GtkTreeStore *)gtk_tree_view_get_model (treeview);
3807 GtkTreeIter iter;
3808 gboolean value;
3809
3810 if (gtk_tree_model_get_iter ((GtkTreeModel *)store, &iter, arg1)){
3811 gtk_tree_model_get ((GtkTreeModel *)store, &iter, CHECKBOX_COLUMN, &value, -1);
3812 value = value? FALSE : TRUE;
3813 gtk_tree_store_set (GTK_TREE_STORE (store), &iter, CHECKBOX_COLUMN, value, -1);
3814 }
3815
3816}
3817
abe346a3 3818
3819/* According to user's selection, update selector(filter)
3820 */
3821
49bf71b5 3822void update_filter(LttvTracesetSelector *s, GtkTreeStore *store )
3823{
ed3b99b6 3824 GtkTreeIter iter, child_iter, child_iter1, child_iter2;
3825 int i, j, k, nb_eventtype;
49bf71b5 3826 LttvTraceSelector * trace;
3827 LttvTracefileSelector * tracefile;
ed3b99b6 3828 LttvEventtypeSelector * eventtype;
3829 gboolean value, value1, value2;
49bf71b5 3830
3831 if(gtk_tree_model_get_iter_first((GtkTreeModel*)store, &iter)){
3832 i = 0;
3833 do{
ed3b99b6 3834 trace = lttv_traceset_selector_trace_get(s, i);
3835 nb_eventtype = lttv_trace_selector_eventtype_number(trace);
49bf71b5 3836 gtk_tree_model_get ((GtkTreeModel*)store, &iter, CHECKBOX_COLUMN, &value,-1);
3837 if(value){
3838 j = 0;
3839 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter, &iter)){
3840 do{
ed3b99b6 3841 if(j<1){//eventtype selector for trace
3842 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter, CHECKBOX_COLUMN, &value2,-1);
3843 if(value2){
3844 k=0;
3845 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter1, &child_iter)){
3846 do{
3847 eventtype = lttv_trace_selector_eventtype_get(trace,k);
3848 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter1, CHECKBOX_COLUMN, &value2,-1);
3849 lttv_eventtype_selector_set_selected(eventtype,value2);
3850 k++;
3851 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter1));
3852 }
3853 }
3854 }else{ //tracefile selector
3855 tracefile = lttv_trace_selector_tracefile_get(trace, j - 1);
3856 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter, CHECKBOX_COLUMN, &value1,-1);
3857 lttv_tracefile_selector_set_selected(tracefile,value1);
3858 if(value1){
3859 gtk_tree_model_iter_children((GtkTreeModel*)store, &child_iter1, &child_iter); //eventtype selector
3860 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter1, CHECKBOX_COLUMN, &value2,-1);
3861 if(value2){
3862 k = 0;
3863 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter2, &child_iter1)){
3864 do{//eventtype selector for tracefile
3865 eventtype = lttv_tracefile_selector_eventtype_get(tracefile,k);
3866 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter2, CHECKBOX_COLUMN, &value2,-1);
3867 lttv_eventtype_selector_set_selected(eventtype,value2);
3868 k++;
3869 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter2));
3870 }
3871 }
3872 }
3873 }
49bf71b5 3874 j++;
3875 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter));
3876 }
3877 }
3878 lttv_trace_selector_set_selected(trace,value);
3879 i++;
3880 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &iter));
3881 }
3882}
3883
abe346a3 3884
3885/* Display a dialogue showing all eventtypes and traces, let user to select the interested
3886 * eventtypes, tracefiles and traces (filter)
3887 */
3888
a8c0f09d 3889gboolean get_filter_selection(LttvTracesetSelector *s,char *title, char * column_title)
49bf71b5 3890{
3891 GtkWidget * dialogue;
3892 GtkTreeStore * store;
3893 GtkWidget * tree;
3894 GtkWidget * scroll_win;
3895 GtkCellRenderer * renderer;
3896 GtkTreeViewColumn * column;
ed3b99b6 3897 GtkTreeIter iter, child_iter, child_iter1, child_iter2;
3898 int i, j, k, id, nb_trace, nb_tracefile, nb_eventtype;
49bf71b5 3899 LttvTraceSelector * trace;
3900 LttvTracefileSelector * tracefile;
ed3b99b6 3901 LttvEventtypeSelector * eventtype;
49bf71b5 3902 char * name;
3903 gboolean checked;
3904
3905 dialogue = gtk_dialog_new_with_buttons(title,
3906 NULL,
3907 GTK_DIALOG_MODAL,
3908 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
3909 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
3910 NULL);
ed3b99b6 3911 gtk_window_set_default_size((GtkWindow*)dialogue, 300, 500);
49bf71b5 3912
3913 store = gtk_tree_store_new (TOTAL_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING);
3914 tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
3915 g_object_unref (G_OBJECT (store));
3916 g_signal_connect (G_OBJECT (tree), "row-activated",
3917 G_CALLBACK (checkbox_changed),
3918 NULL);
3919
3920
3921 renderer = gtk_cell_renderer_toggle_new ();
3922 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle *)renderer, FALSE);
3923
3924 g_object_set (G_OBJECT (renderer),"activatable", TRUE, NULL);
3925
3926 column = gtk_tree_view_column_new_with_attributes ("Checkbox",
3927 renderer,
3928 "active", CHECKBOX_COLUMN,
3929 NULL);
3930 gtk_tree_view_column_set_alignment (column, 0.5);
3931 gtk_tree_view_column_set_fixed_width (column, 20);
3932 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
3933
3934 renderer = gtk_cell_renderer_text_new ();
3935 column = gtk_tree_view_column_new_with_attributes (column_title,
3936 renderer,
3937 "text", NAME_COLUMN,
3938 NULL);
3939 gtk_tree_view_column_set_alignment (column, 0.0);
3940 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
3941 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree), FALSE);
3942
3943 scroll_win = gtk_scrolled_window_new (NULL, NULL);
3944 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
3945 GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
3946 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
3947
3948 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
3949
3950 gtk_widget_show(scroll_win);
3951 gtk_widget_show(tree);
3952
ed3b99b6 3953 nb_trace = lttv_traceset_selector_trace_number(s);
49bf71b5 3954 for(i=0;i<nb_trace;i++){
ed3b99b6 3955 trace = lttv_traceset_selector_trace_get(s, i);
49bf71b5 3956 name = lttv_trace_selector_get_name(trace);
3957 gtk_tree_store_append (store, &iter, NULL);
3958 checked = lttv_trace_selector_get_selected(trace);
3959 gtk_tree_store_set (store, &iter,
3960 CHECKBOX_COLUMN,checked,
3961 NAME_COLUMN,name,
3962 -1);
ed3b99b6 3963
3964 gtk_tree_store_append (store, &child_iter, &iter);
3965 gtk_tree_store_set (store, &child_iter,
3966 CHECKBOX_COLUMN, checked,
3967 NAME_COLUMN,"eventtype",
3968 -1);
3969
3970 nb_eventtype = lttv_trace_selector_eventtype_number(trace);
3971 for(j=0;j<nb_eventtype;j++){
3972 eventtype = lttv_trace_selector_eventtype_get(trace,j);
3973 name = lttv_eventtype_selector_get_name(eventtype);
3974 checked = lttv_eventtype_selector_get_selected(eventtype);
3975 gtk_tree_store_append (store, &child_iter1, &child_iter);
3976 gtk_tree_store_set (store, &child_iter1,
3977 CHECKBOX_COLUMN, checked,
3978 NAME_COLUMN,name,
3979 -1);
3980 }
3981
3982 nb_tracefile = lttv_trace_selector_tracefile_number(trace);
49bf71b5 3983 for(j=0;j<nb_tracefile;j++){
ed3b99b6 3984 tracefile = lttv_trace_selector_tracefile_get(trace, j);
49bf71b5 3985 name = lttv_tracefile_selector_get_name(tracefile);
3986 gtk_tree_store_append (store, &child_iter, &iter);
3987 checked = lttv_tracefile_selector_get_selected(tracefile);
3988 gtk_tree_store_set (store, &child_iter,
3989 CHECKBOX_COLUMN, checked,
3990 NAME_COLUMN,name,
3991 -1);
ed3b99b6 3992
3993 gtk_tree_store_append (store, &child_iter1, &child_iter);
3994 gtk_tree_store_set (store, &child_iter1,
3995 CHECKBOX_COLUMN, checked,
3996 NAME_COLUMN,"eventtype",
3997 -1);
3998
3999 for(k=0;k<nb_eventtype;k++){
4000 eventtype = lttv_tracefile_selector_eventtype_get(tracefile,k);
4001 name = lttv_eventtype_selector_get_name(eventtype);
4002 checked = lttv_eventtype_selector_get_selected(eventtype);
4003 gtk_tree_store_append (store, &child_iter2, &child_iter1);
4004 gtk_tree_store_set (store, &child_iter2,
4005 CHECKBOX_COLUMN, checked,
4006 NAME_COLUMN,name,
4007 -1);
4008 }
49bf71b5 4009 }
4010 }
4011
4012 id = gtk_dialog_run(GTK_DIALOG(dialogue));
4013 switch(id){
4014 case GTK_RESPONSE_ACCEPT:
4015 case GTK_RESPONSE_OK:
4016 update_filter(s, store);
a8c0f09d 4017 gtk_widget_destroy(dialogue);
4018 return TRUE;
49bf71b5 4019 case GTK_RESPONSE_REJECT:
4020 case GTK_RESPONSE_CANCEL:
4021 default:
4022 gtk_widget_destroy(dialogue);
4023 break;
4024 }
a8c0f09d 4025 return FALSE;
49bf71b5 4026}
4027
abe346a3 4028
4029/* Select a trace which will be removed from traceset
4030 */
4031
2176f952 4032char * get_remove_trace(char ** all_trace_name, int nb_trace)
4033{
4034 return get_selection(all_trace_name, nb_trace,
4035 "Select a trace", "Trace pathname");
4036}
abe346a3 4037
4038
b052368a 4039/* Select a module which will be loaded
4040 */
4041
4042char * get_load_module(char ** load_module_name, int nb_module)
4043{
4044 return get_selection(load_module_name, nb_module,
4045 "Select a module to load", "Module name");
4046}
4047
4048
4049
4050
abe346a3 4051/* Select a module which will be unloaded
4052 */
4053
36b3c068 4054char * get_unload_module(char ** loaded_module_name, int nb_module)
2176f952 4055{
4056 return get_selection(loaded_module_name, nb_module,
b052368a 4057 "Select a module to unload", "Module name");
2176f952 4058}
4059
abe346a3 4060
4061/* Display a dialogue which shows all selectable items, let user to
4062 * select one of them
4063 */
4064
2176f952 4065char * get_selection(char ** loaded_module_name, int nb_module,
4066 char *title, char * column_title)
36b3c068 4067{
4068 GtkWidget * dialogue;
4069 GtkWidget * scroll_win;
4070 GtkWidget * tree;
4071 GtkListStore * store;
4072 GtkTreeViewColumn * column;
4073 GtkCellRenderer * renderer;
4074 GtkTreeSelection * select;
4075 GtkTreeIter iter;
4076 gint id, i;
4077 char * unload_module_name = NULL;
4078
2176f952 4079 dialogue = gtk_dialog_new_with_buttons(title,
36b3c068 4080 NULL,
4081 GTK_DIALOG_MODAL,
4082 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
4083 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
4084 NULL);
4085 gtk_window_set_default_size((GtkWindow*)dialogue, 500, 200);
4086
4087 scroll_win = gtk_scrolled_window_new (NULL, NULL);
4088 gtk_widget_show ( scroll_win);
4089 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
4090 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
4091
4092 store = gtk_list_store_new (N_COLUMNS,G_TYPE_STRING);
4093 tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL (store));
4094 gtk_widget_show ( tree);
4095 g_object_unref (G_OBJECT (store));
4096
4097 renderer = gtk_cell_renderer_text_new ();
2176f952 4098 column = gtk_tree_view_column_new_with_attributes (column_title,
36b3c068 4099 renderer,
4100 "text", MODULE_COLUMN,
4101 NULL);
4102 gtk_tree_view_column_set_alignment (column, 0.5);
4103 gtk_tree_view_column_set_fixed_width (column, 150);
4104 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
4105
4106 select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
4107 gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
4108
4109 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
4110
4111 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
4112
4113 for(i=0;i<nb_module;i++){
4114 gtk_list_store_append (store, &iter);
4115 gtk_list_store_set (store, &iter, MODULE_COLUMN,loaded_module_name[i],-1);
4116 }
4117
4118 id = gtk_dialog_run(GTK_DIALOG(dialogue));
4119 switch(id){
4120 case GTK_RESPONSE_ACCEPT:
4121 case GTK_RESPONSE_OK:
4122 if (gtk_tree_selection_get_selected (select, (GtkTreeModel**)&store, &iter)){
4123 gtk_tree_model_get ((GtkTreeModel*)store, &iter, MODULE_COLUMN, &unload_module_name, -1);
4124 }
4125 case GTK_RESPONSE_REJECT:
4126 case GTK_RESPONSE_CANCEL:
4127 default:
4128 gtk_widget_destroy(dialogue);
4129 break;
4130 }
4131
4132 return unload_module_name;
4133}
5723fa24 4134
abe346a3 4135
ef68c3ac 4136/* Insert all menu entry and tool buttons into this main window
001d8606 4137 * for modules.
4138 *
abe346a3 4139 */
4140
6c9d86dd 4141void add_all_menu_toolbar_constructors(MainWindow * mw, gpointer user_data)
5723fa24 4142{
4143 int i;
4144 GdkPixbuf *pixbuf;
42fcbb71 4145 lttvwindow_viewer_constructor constructor;
001d8606 4146 LttvMenus * global_menu, * instance_menu;
4147 LttvToolbars * global_toolbar, * instance_toolbar;
6c9d86dd 4148 LttvMenuClosure *menu_item;
4149 LttvToolbarClosure *toolbar_item;
5723fa24 4150 LttvAttributeValue value;
001d8606 4151 LttvIAttribute *global_attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
501e4e70 4152 LttvIAttribute *attributes = mw->attributes;
001d8606 4153 GtkWidget * tool_menu_title_menu, *new_widget, *pixmap;
4154
4155 g_assert(lttv_iattribute_find_by_path(global_attributes,
4156 "viewers/menu", LTTV_POINTER, &value));
4157 if(*(value.v_pointer) == NULL)
501e4e70 4158 *(value.v_pointer) = lttv_menus_new();
001d8606 4159 global_menu = (LttvMenus*)*(value.v_pointer);
5723fa24 4160
4161 g_assert(lttv_iattribute_find_by_path(attributes,
4162 "viewers/menu", LTTV_POINTER, &value));
001d8606 4163 if(*(value.v_pointer) == NULL)
501e4e70 4164 *(value.v_pointer) = lttv_menus_new();
001d8606 4165 instance_menu = (LttvMenus*)*(value.v_pointer);
5723fa24 4166
001d8606 4167
4168
4169 g_assert(lttv_iattribute_find_by_path(global_attributes,
4170 "viewers/toolbar", LTTV_POINTER, &value));
4171 if(*(value.v_pointer) == NULL)
501e4e70 4172 *(value.v_pointer) = lttv_toolbars_new();
001d8606 4173 global_toolbar = (LttvToolbars*)*(value.v_pointer);
4174
4175 g_assert(lttv_iattribute_find_by_path(attributes,
4176 "viewers/toolbar", LTTV_POINTER, &value));
4177 if(*(value.v_pointer) == NULL)
501e4e70 4178 *(value.v_pointer) = lttv_toolbars_new();
001d8606 4179 instance_toolbar = (LttvToolbars*)*(value.v_pointer);
4180
4181 /* Add missing menu entries to window instance */
4182 for(i=0;i<global_menu->len;i++) {
6c9d86dd 4183 menu_item = &g_array_index(global_menu, LttvMenuClosure, i);
4184
4185 //add menu_item to window instance;
4186 constructor = menu_item->con;
4187 tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
4188 new_widget =
501e4e70 4189 gtk_menu_item_new_with_mnemonic (menu_item->menu_text);
6c9d86dd 4190 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu),
4191 new_widget);
4192 g_signal_connect ((gpointer) new_widget, "activate",
4193 G_CALLBACK (insert_viewer_wrap),
4194 constructor);
4195 gtk_widget_show (new_widget);
4196 lttv_menus_add(instance_menu, menu_item->con,
4197 menu_item->menu_path,
4198 menu_item->menu_text,
4199 new_widget);
001d8606 4200
001d8606 4201 }
4202
4203 /* Add missing toolbar entries to window instance */
4204 for(i=0;i<global_toolbar->len;i++) {
6c9d86dd 4205 toolbar_item = &g_array_index(global_toolbar, LttvToolbarClosure, i);
4206
4207 //add toolbar_item to window instance;
4208 constructor = toolbar_item->con;
4209 tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1");
4210 pixbuf = gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item->pixmap);
4211 pixmap = gtk_image_new_from_pixbuf(pixbuf);
4212 new_widget =
4213 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu),
4214 GTK_TOOLBAR_CHILD_BUTTON,
4215 NULL,
4216 "",
4217 toolbar_item->tooltip, NULL,
4218 pixmap, NULL, NULL);
4219 gtk_label_set_use_underline(
4220 GTK_LABEL (((GtkToolbarChild*) (
4221 g_list_last (GTK_TOOLBAR
4222 (tool_menu_title_menu)->children)->data))->label),
4223 TRUE);
4224 gtk_container_set_border_width (GTK_CONTAINER (new_widget), 1);
4225 g_signal_connect ((gpointer) new_widget,
4226 "clicked",
4227 G_CALLBACK (insert_viewer_wrap),
4228 constructor);
4229 gtk_widget_show (new_widget);
001d8606 4230
6c9d86dd 4231 lttv_toolbars_add(instance_toolbar, toolbar_item->con,
4232 toolbar_item->tooltip,
4233 toolbar_item->pixmap,
4234 new_widget);
001d8606 4235
5723fa24 4236 }
6c9d86dd 4237
5723fa24 4238}
4239
abe346a3 4240
4241/* Create a main window
4242 */
4243
08b1c66e 4244void construct_main_window(MainWindow * parent)
5723fa24 4245{
2a2fa4f0 4246 g_debug("construct_main_window()");
68b48a45 4247 GtkWidget * new_window; /* New generated main window */
bca3b81f 4248 MainWindow * new_m_window;/* New main window structure */
5723fa24 4249 GtkNotebook * notebook;
f7afe191 4250 LttvIAttribute *attributes =
4251 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
4252 LttvAttributeValue value;
6ced96ef 4253 Tab *new_tab;
2061e03d 4254
bca3b81f 4255 new_m_window = g_new(MainWindow, 1);
5723fa24 4256
4257 // Add the object's information to the module's array
68b48a45 4258 g_main_window_list = g_slist_append(g_main_window_list, new_m_window);
5723fa24 4259
68b48a45 4260 new_window = create_MWindow();
4261 gtk_widget_show (new_window);
5723fa24 4262
bca3b81f 4263 new_m_window->mwindow = new_window;
a43d67ba 4264 new_m_window->attributes = attributes;
5723fa24 4265
001d8606 4266 g_assert(lttv_iattribute_find_by_path(attributes,
4267 "viewers/menu", LTTV_POINTER, &value));
501e4e70 4268 *(value.v_pointer) = lttv_menus_new();
001d8606 4269
501e4e70 4270 g_assert(lttv_iattribute_find_by_path(attributes,
001d8606 4271 "viewers/toolbar", LTTV_POINTER, &value));
501e4e70 4272 *(value.v_pointer) = lttv_toolbars_new();
2061e03d 4273
6c9d86dd 4274 add_all_menu_toolbar_constructors(new_m_window, NULL);
5723fa24 4275
2d262115 4276 g_object_set_data_full(G_OBJECT(new_window),
4277 "main_window_data",
4278 (gpointer)new_m_window,
4279 (GDestroyNotify)g_free);
5723fa24 4280 //create a default tab
bca3b81f 4281 notebook = (GtkNotebook *)lookup_widget(new_m_window->mwindow, "MNotebook");
5723fa24 4282 if(notebook == NULL){
4283 g_printf("Notebook does not exist\n");
4284 return;
4285 }
e800cf84 4286 //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
5723fa24 4287 //for now there is no name field in LttvTraceset structure
4288 //Use "Traceset" as the label for the default tab
6ced96ef 4289 if(parent) {
4290 GtkWidget * parent_notebook = lookup_widget(parent->mwindow, "MNotebook");
4291 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook),
4292 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook)));
4293 Tab *parent_tab;
4294
4295 if(!page) {
4296 parent_tab = NULL;
4297 } else {
4298 parent_tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
4299 }
4300 new_tab = create_tab(new_m_window, parent_tab, notebook, "Traceset");
4301 } else {
4302 new_tab = create_tab(new_m_window, NULL, notebook, "Traceset");
91fd6881 4303 /* First window, use command line trace */
4266dc7f 4304 if(g_init_trace != NULL){
6ced96ef 4305 lttvwindow_add_trace(new_tab,
4266dc7f 4306 g_init_trace);
91fd6881 4307
4266dc7f 4308 }
e800cf84 4309 LttvTraceset *traceset = new_tab->traceset_info->traceset;
4310 SetTraceset(new_tab, traceset);
4266dc7f 4311 }
5723fa24 4312
ef68c3ac 4313 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list));
5723fa24 4314}
4315
abe346a3 4316
4317/* Free the memory occupied by a tab structure
4318 * destroy the tab
4319 */
4320
bca3b81f 4321void tab_destructor(Tab * tab_instance)
f7afe191 4322{
716e4367 4323 int i, nb, ref_count;
4324 LttvTrace * trace;
4325
bca3b81f 4326 if(tab_instance->attributes)
501e4e70 4327 g_object_unref(tab_instance->attributes);
4328
4329 if(tab_instance->interrupted_state)
4330 g_object_unref(tab_instance->interrupted_state);
4331
2061e03d 4332
716e4367 4333 if(tab_instance->traceset_info->traceset_context != NULL){
784705cc 4334 //remove state update hooks
4335 lttv_state_remove_event_hooks(
4336 (LttvTracesetState*)tab_instance->traceset_info->
4337 traceset_context);
716e4367 4338 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab_instance->traceset_info->
4339 traceset_context));
4340 g_object_unref(tab_instance->traceset_info->traceset_context);
4341 }
4342 if(tab_instance->traceset_info->traceset != NULL) {
4343 nb = lttv_traceset_number(tab_instance->traceset_info->traceset);
4344 for(i = 0 ; i < nb ; i++) {
4345 trace = lttv_traceset_get(tab_instance->traceset_info->traceset, i);
4346 ref_count = lttv_trace_get_ref_number(trace);
49bf71b5 4347 if(ref_count <= 1){
a1a2b649 4348 ltt_trace_close(lttv_trace(trace));
49bf71b5 4349 }
716e4367 4350 }
4351 }
a43d67ba 4352 lttv_traceset_destroy(tab_instance->traceset_info->traceset);
501e4e70 4353 /* Remove the idle events requests processing function of the tab */
4354 g_idle_remove_by_data(tab_instance);
4355
4356 g_slist_free(tab_instance->events_requests);
716e4367 4357 g_free(tab_instance->traceset_info);
68b48a45 4358 g_free(tab_instance);
f7afe191 4359}
4360
abe346a3 4361
4362/* Create a tab and insert it into the current main window
4363 */
4364
6ced96ef 4365Tab* create_tab(MainWindow * mw, Tab *copy_tab,
716e4367 4366 GtkNotebook * notebook, char * label)
5723fa24 4367{
4368 GList * list;
6ced96ef 4369 Tab * tab;
68b48a45 4370 LttTime tmp_time;
a43d67ba 4371
abe346a3 4372 //create a new tab data structure
6ced96ef 4373 tab = g_new(Tab,1);
716e4367 4374
abe346a3 4375 //construct and initialize the traceset_info
6ced96ef 4376 tab->traceset_info = g_new(TracesetInfo,1);
a43d67ba 4377
4266dc7f 4378 if(copy_tab) {
6ced96ef 4379 tab->traceset_info->traceset =
4266dc7f 4380 lttv_traceset_copy(copy_tab->traceset_info->traceset);
4381 } else {
6ced96ef 4382 tab->traceset_info->traceset = lttv_traceset_new();
716e4367 4383 }
20fde85f 4384
84ddf5c9 4385#ifdef DEBUG
20fde85f 4386 lttv_attribute_write_xml(
6ced96ef 4387 lttv_traceset_attribute(tab->traceset_info->traceset),
20fde85f 4388 stdout,
4389 0, 4);
4390 fflush(stdout);
84ddf5c9 4391#endif //DEBUG
20fde85f 4392
e800cf84 4393 tab->time_manager_lock = FALSE;
4394 tab->current_time_manager_lock = FALSE;
20fde85f 4395
716e4367 4396 //FIXME copy not implemented in lower level
6ced96ef 4397 tab->traceset_info->traceset_context =
716e4367 4398 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
6ced96ef 4399 g_assert(tab->traceset_info->traceset_context != NULL);
716e4367 4400 lttv_context_init(
6ced96ef 4401 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context),
4402 tab->traceset_info->traceset);
784705cc 4403 //add state update hooks
4404 lttv_state_add_event_hooks(
6ced96ef 4405 (LttvTracesetState*)tab->traceset_info->traceset_context);
784705cc 4406
abe346a3 4407 //determine the current_time and time_window of the tab
e800cf84 4408#if 0
6ced96ef 4409 if(copy_tab != NULL){
4410 tab->time_window = copy_tab->time_window;
4411 tab->current_time = copy_tab->current_time;
5723fa24 4412 }else{
6ced96ef 4413 tab->time_window.start_time =
4414 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4415 time_span.start_time;
f7afe191 4416 if(DEFAULT_TIME_WIDTH_S <
6ced96ef 4417 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4418 time_span.end_time.tv_sec)
68b48a45 4419 tmp_time.tv_sec = DEFAULT_TIME_WIDTH_S;
f7afe191 4420 else
68b48a45 4421 tmp_time.tv_sec =
6ced96ef 4422 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4423 time_span.end_time.tv_sec;
68b48a45 4424 tmp_time.tv_nsec = 0;
6ced96ef 4425 tab->time_window.time_width = tmp_time ;
4426 tab->current_time.tv_sec =
4427 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4428 time_span.start_time.tv_sec;
4429 tab->current_time.tv_nsec =
4430 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
4431 time_span.start_time.tv_nsec;
5723fa24 4432 }
e800cf84 4433#endif //0
6ced96ef 4434 tab->attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
4435 tab->interrupted_state = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
b052368a 4436
58f6c2a4 4437 tab->vbox = gtk_vbox_new(FALSE, 2);
4438 tab->viewer_container = gtk_vbox_new(TRUE, 2);
b052368a 4439 tab->scrollbar = gtk_hscrollbar_new(NULL);
4440 //tab->multivpaned = gtk_multi_vpaned_new();
4441
4442 gtk_box_pack_start(GTK_BOX(tab->vbox),
4443 tab->viewer_container,
4444 TRUE, /* expand */
4445 TRUE, /* Give the extra space to the child */
4446 0); /* No padding */
e800cf84 4447
4448 /* Create the timebar */
4449 {
4450 tab->MTimebar = gtk_hbox_new(FALSE, 2);
4451 gtk_widget_show(tab->MTimebar);
f02b5e22 4452 GtkTooltips *tooltips = gtk_tooltips_new();
4453
4454 tab->MEventBox1a = gtk_event_box_new();
4455 gtk_widget_show(tab->MEventBox1a);
4456 gtk_tooltips_set_tip(tooltips, tab->MEventBox1a,
4457 "Paste Start and End Times Here", "");
4458 tab->MText1a = gtk_label_new("Time Frame ");
4459 gtk_widget_show(tab->MText1a);
4460 gtk_container_add(GTK_CONTAINER(tab->MEventBox1a), tab->MText1a);
4461 tab->MEventBox1b = gtk_event_box_new();
4462 gtk_widget_show(tab->MEventBox1b);
4463 gtk_tooltips_set_tip(tooltips, tab->MEventBox1b,
4464 "Paste Start Time Here", "");
4465 tab->MText1b = gtk_label_new("start: ");
4466 gtk_widget_show(tab->MText1b);
4467 gtk_container_add(GTK_CONTAINER(tab->MEventBox1b), tab->MText1b);
e800cf84 4468 tab->MText2 = gtk_label_new("s");
4469 gtk_widget_show(tab->MText2);
4470 tab->MText3a = gtk_label_new("ns");
4471 gtk_widget_show(tab->MText3a);
f02b5e22 4472 tab->MEventBox3b = gtk_event_box_new();
4473 gtk_widget_show(tab->MEventBox3b);
4474 gtk_tooltips_set_tip(tooltips, tab->MEventBox3b,
4475 "Paste End Time Here", "");
e800cf84 4476 tab->MText3b = gtk_label_new("end:");
4477 gtk_widget_show(tab->MText3b);
f02b5e22 4478 gtk_container_add(GTK_CONTAINER(tab->MEventBox3b), tab->MText3b);
e800cf84 4479 tab->MText4 = gtk_label_new("s");
4480 gtk_widget_show(tab->MText4);
4481 tab->MText5a = gtk_label_new("ns");
4482 gtk_widget_show(tab->MText5a);
f02b5e22 4483 tab->MEventBox5b = gtk_event_box_new();
4484 gtk_widget_show(tab->MEventBox5b);
4485 gtk_tooltips_set_tip(tooltips, tab->MEventBox5b,
4486 "Paste Current Time Here", "");
e800cf84 4487 tab->MText5b = gtk_label_new("Current Time:");
4488 gtk_widget_show(tab->MText5b);
f02b5e22 4489 gtk_container_add(GTK_CONTAINER(tab->MEventBox5b), tab->MText5b);
e800cf84 4490 tab->MText6 = gtk_label_new("s");
4491 gtk_widget_show(tab->MText6);
4492 tab->MText7 = gtk_label_new("ns");
4493 gtk_widget_show(tab->MText7);
4494
4495 tab->MEntry1 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4496 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry1),0);
4497 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry1),TRUE);
4498 gtk_widget_show(tab->MEntry1);
4499 tab->MEntry2 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4500 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry2),0);
4501 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry2),TRUE);
4502 gtk_widget_show(tab->MEntry2);
4503 tab->MEntry3 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4504 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry3),0);
4505 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry3),TRUE);
4506 gtk_widget_show(tab->MEntry3);
4507 tab->MEntry4 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4508 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry4),0);
4509 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry4),TRUE);
4510 gtk_widget_show(tab->MEntry4);
4511 tab->MEntry5 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4512 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry5),0);
4513 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry5),TRUE);
4514 gtk_widget_show(tab->MEntry5);
4515 tab->MEntry6 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
4516 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry6),0);
4517 gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry6),TRUE);
4518 gtk_widget_show(tab->MEntry6);
4519
4520
4521 GtkWidget *temp_widget;
4522
f02b5e22 4523 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEventBox1a, FALSE,
4524 FALSE, 0);
4525 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEventBox1b, FALSE,
4526 FALSE, 0);
e800cf84 4527 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry1, FALSE, FALSE, 0);
4528 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText2, FALSE, FALSE, 0);
4529 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry2, FALSE, FALSE, 0);
4530 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText3a, FALSE, FALSE, 0);
4531 temp_widget = gtk_vseparator_new();
4532 gtk_widget_show(temp_widget);
4533 gtk_box_pack_start (GTK_BOX (tab->MTimebar), temp_widget, FALSE, FALSE, 0);
f02b5e22 4534 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEventBox3b, FALSE,
4535 FALSE, 0);
e800cf84 4536 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry3, FALSE, FALSE, 0);
4537 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText4, FALSE, FALSE, 0);
4538 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry4, FALSE, FALSE, 0);
4539 gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText5a, FALSE, FALSE, 0);
4540 temp_widget = gtk_vseparator_new();
4541 gtk_widget_show(temp_widget);
4542 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MText7, FALSE, FALSE, 0);
4543 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MEntry6, FALSE, FALSE, 0);
4544 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MText6, FALSE, FALSE, 0);
4545 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MEntry5, FALSE, FALSE, 0);
f02b5e22 4546 gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MEventBox5b, FALSE,
4547 FALSE, 0);
e800cf84 4548 gtk_box_pack_end (GTK_BOX (tab->MTimebar), temp_widget, FALSE, FALSE, 0);
f02b5e22 4549
4550
4551 //GtkWidget *test = gtk_button_new_with_label("drop");
4552 //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
4553 //gtk_widget_show(test);
4554 //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
4555 //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
4556 /*GtkWidget *event_box = gtk_event_box_new();
4557 gtk_widget_show(event_box);
4558 gtk_tooltips_set_tip(tooltips, event_box,
4559 "Paste Current Time Here", "");
4560 gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
4561 GtkWidget *test = gtk_label_new("drop");
4562 gtk_container_add(GTK_CONTAINER(event_box), test);
4563 gtk_widget_show(test);
4564 g_signal_connect (G_OBJECT(event_box),
4565 "button-press-event",
4566 G_CALLBACK (on_MText1_paste),
4567 (gpointer)tab);
4568*/
4569
4570 g_signal_connect (G_OBJECT(tab->MEventBox1a),
4571 "button-press-event",
4572 G_CALLBACK (on_MEventBox1a_paste),
4573 (gpointer)tab);
4574
4575 g_signal_connect (G_OBJECT(tab->MEventBox1b),
4576 "button-press-event",
4577 G_CALLBACK (on_MEventBox1b_paste),
4578 (gpointer)tab);
4579 g_signal_connect (G_OBJECT(tab->MEventBox3b),
4580 "button-press-event",
4581 G_CALLBACK (on_MEventBox3b_paste),
4582 (gpointer)tab);
4583 g_signal_connect (G_OBJECT(tab->MEventBox5b),
4584 "button-press-event",
4585 G_CALLBACK (on_MEventBox5b_paste),
4586 (gpointer)tab);
e800cf84 4587 }
4588
b052368a 4589 gtk_box_pack_end(GTK_BOX(tab->vbox),
4590 tab->scrollbar,
4591 FALSE, /* Do not expand */
4592 FALSE, /* Fill has no effect here (expand false) */
4593 0); /* No padding */
e800cf84 4594
4595 gtk_box_pack_end(GTK_BOX(tab->vbox),
4596 tab->MTimebar,
4597 FALSE, /* Do not expand */
4598 FALSE, /* Fill has no effect here (expand false) */
4599 0); /* No padding */
4600
b052368a 4601 g_object_set_data(G_OBJECT(tab->viewer_container), "focused_viewer", NULL);
4602
4603
6ced96ef 4604 tab->mw = mw;
27a559b9 4605
3c031040 4606 /*{
4607 // Display a label with a X
27a559b9 4608 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
4609 GtkWidget *w_label = gtk_label_new (label);
4610 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
4611 GtkWidget *w_button = gtk_button_new ();
4612 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
4613 //GtkWidget *w_button = gtk_button_new_with_label("x");
4614
4615 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
4616
4617 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
4618 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
4619 FALSE, 0);
a43d67ba 4620
27a559b9 4621 g_signal_connect_swapped (w_button, "clicked",
4622 G_CALLBACK (on_close_tab_X_clicked),
4623 tab->multi_vpaned);
5723fa24 4624
3c031040 4625 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
4626
27a559b9 4627 gtk_widget_show (w_label);
4628 gtk_widget_show (pixmap);
4629 gtk_widget_show (w_button);
4630 gtk_widget_show (w_hbox);
4631
4632 tab->label = w_hbox;
3c031040 4633 }*/
4634
4635
4636 tab->label = gtk_label_new (label);
b052368a 4637
4638 gtk_widget_show(tab->label);
4639 gtk_widget_show(tab->scrollbar);
4640 gtk_widget_show(tab->viewer_container);
4641 gtk_widget_show(tab->vbox);
4642 //gtk_widget_show(tab->multivpaned);
3c031040 4643
4644
501e4e70 4645 /* Start with empty events requests list */
6ced96ef 4646 tab->events_requests = NULL;
4647 tab->events_request_pending = FALSE;
a43d67ba 4648
f7afe191 4649 g_object_set_data_full(
b052368a 4650 G_OBJECT(tab->vbox),
f7afe191 4651 "Tab_Info",
6ced96ef 4652 tab,
4653 (GDestroyNotify)tab_destructor);
540edb40 4654
b052368a 4655 g_signal_connect(G_OBJECT(tab->scrollbar), "value-changed",
4656 G_CALLBACK(scroll_value_changed_cb), tab);
e800cf84 4657
4658 g_signal_connect ((gpointer) tab->MEntry1, "value-changed",
4659 G_CALLBACK (on_MEntry1_value_changed),
4660 tab);
4661 g_signal_connect ((gpointer) tab->MEntry2, "value-changed",
4662 G_CALLBACK (on_MEntry2_value_changed),
4663 tab);
4664 g_signal_connect ((gpointer) tab->MEntry3, "value-changed",
4665 G_CALLBACK (on_MEntry3_value_changed),
4666 tab);
4667 g_signal_connect ((gpointer) tab->MEntry4, "value-changed",
4668 G_CALLBACK (on_MEntry4_value_changed),
4669 tab);
4670 g_signal_connect ((gpointer) tab->MEntry5, "value-changed",
4671 G_CALLBACK (on_MEntry5_value_changed),
4672 tab);
4673 g_signal_connect ((gpointer) tab->MEntry6, "value-changed",
4674 G_CALLBACK (on_MEntry6_value_changed),
4675 tab);
4676
b052368a 4677 //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
4678 // G_CALLBACK(scroll_value_changed_cb), tab);
4679
4680
784705cc 4681 //insert tab into notebook
6ced96ef 4682 gtk_notebook_append_page(notebook,
b052368a 4683 tab->vbox,
4684 tab->label);
5723fa24 4685 list = gtk_container_get_children(GTK_CONTAINER(notebook));
4686 gtk_notebook_set_current_page(notebook,g_list_length(list)-1);
a43d67ba 4687 // always show : not if(g_list_length(list)>1)
4688 gtk_notebook_set_show_tabs(notebook, TRUE);
4689
6ced96ef 4690 return tab;
a43d67ba 4691}
4692
501e4e70 4693/*
4694 * execute_events_requests
4695 *
4696 * Idle function that executes the pending requests for a tab.
4697 *
4698 * @return return value : TRUE : keep the idle function, FALSE : remove it.
4699 */
4700gboolean execute_events_requests(Tab *tab)
a43d67ba 4701{
501e4e70 4702 return ( lttvwindow_process_pending_requests(tab) );
a43d67ba 4703}
4704
This page took 0.262986 seconds and 4 git commands to generate.