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