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