fixed creation/destroy of main window symmetry
[lttv.git] / ltt / branches / poly / lttv / modules / gui / lttvwindow / lttvwindow / callbacks.c
1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 XangXiu Yang
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 <gtk/gtk.h>
24
25 #include "callbacks.h"
26 #include "interface.h"
27 #include "support.h"
28 #include <ltt/trace.h>
29 #include <ltt/facility.h>
30 #include <ltt/time.h>
31 #include <ltt/event.h>
32 #include <lttv/lttv.h>
33 #include <lttv/module.h>
34 #include <lttv/iattribute.h>
35 #include <lttv/stats.h>
36 #include <lttvwindow/mainwindow.h>
37 #include <lttvwindow/menu.h>
38 #include <lttvwindow/toolbar.h>
39 #include <lttvwindow/viewer.h>
40 #include <lttvwindow/gtkdirsel.h>
41 #include <lttvwindow/lttvfilter.h>
42
43 #define PATH_LENGTH 256
44 #define DEFAULT_TIME_WIDTH_S 1
45
46 extern LttvTrace *g_init_trace ;
47
48
49 /** Array containing instanced objects. */
50 extern GSList * g_main_window_list;
51
52 static int g_win_count = 0;
53
54 /** MD : keep old directory. */
55 static char remember_plugins_dir[PATH_LENGTH] = "";
56 static char remember_trace_dir[PATH_LENGTH] = "";
57
58
59 MainWindow * get_window_data_struct(GtkWidget * widget);
60 char * get_unload_module(char ** loaded_module_name, int nb_module);
61 char * get_remove_trace(char ** all_trace_name, int nb_trace);
62 char * get_selection(char ** all_name, int nb, char *title, char * column_title);
63 gboolean get_filter_selection(LttvTracesetSelector *s, char *title, char * column_title);
64 void * create_tab(MainWindow * parent, MainWindow * current_window,
65 GtkNotebook * notebook, char * label);
66
67 void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor);
68 void update_filter(LttvTracesetSelector *s, GtkTreeStore *store );
69
70 void checkbox_changed(GtkTreeView *treeview,
71 GtkTreePath *arg1,
72 GtkTreeViewColumn *arg2,
73 gpointer user_data);
74 void remove_trace_from_traceset_selector(GtkMultiVPaned * paned, unsigned i);
75 void add_trace_into_traceset_selector(GtkMultiVPaned * paned, LttTrace * trace);
76
77 LttvTracesetSelector * construct_traceset_selector(LttvTraceset * traceset);
78
79 void call_pending_read_hooks(MainWindow * mw_data);
80 unsigned get_max_event_number(MainWindow * mw_data);
81
82 enum {
83 CHECKBOX_COLUMN,
84 NAME_COLUMN,
85 TOTAL_COLUMNS
86 };
87
88 enum
89 {
90 MODULE_COLUMN,
91 N_COLUMNS
92 };
93
94 /* Construct a selector(filter), which will be associated with a viewer,
95 * and provides an interface for user to select interested events and traces
96 */
97
98 LttvTracesetSelector * construct_traceset_selector(LttvTraceset * traceset)
99 {
100 LttvTracesetSelector * s;
101 LttvTraceSelector * trace;
102 LttvTracefileSelector * tracefile;
103 LttvEventtypeSelector * eventtype;
104 int i, j, k, m;
105 int nb_trace, nb_tracefile, nb_control, nb_per_cpu, nb_facility, nb_event;
106 LttvTrace * trace_v;
107 LttTrace * t;
108 LttTracefile *tf;
109 LttFacility * fac;
110 LttEventType * et;
111
112 s = lttv_traceset_selector_new(lttv_traceset_name(traceset));
113 nb_trace = lttv_traceset_number(traceset);
114 for(i=0;i<nb_trace;i++){
115 trace_v = lttv_traceset_get(traceset, i);
116 t = lttv_trace(trace_v);
117 trace = lttv_trace_selector_new(t);
118 lttv_traceset_selector_trace_add(s, trace);
119
120 nb_facility = ltt_trace_facility_number(t);
121 for(k=0;k<nb_facility;k++){
122 fac = ltt_trace_facility_get(t,k);
123 nb_event = (int) ltt_facility_eventtype_number(fac);
124 for(m=0;m<nb_event;m++){
125 et = ltt_facility_eventtype_get(fac,m);
126 eventtype = lttv_eventtype_selector_new(et);
127 lttv_trace_selector_eventtype_add(trace, eventtype);
128 }
129 }
130
131 nb_control = ltt_trace_control_tracefile_number(t);
132 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(t);
133 nb_tracefile = nb_control + nb_per_cpu;
134
135 for(j = 0 ; j < nb_tracefile ; j++) {
136 if(j < nb_control)
137 tf = ltt_trace_control_tracefile_get(t, j);
138 else
139 tf = ltt_trace_per_cpu_tracefile_get(t, j - nb_control);
140 tracefile = lttv_tracefile_selector_new(tf);
141 lttv_trace_selector_tracefile_add(trace, tracefile);
142 lttv_eventtype_selector_copy(trace, tracefile);
143 }
144 }
145 return s;
146 }
147
148
149 /* insert_viewer function constructs an instance of a viewer first,
150 * then inserts the widget of the instance into the container of the
151 * main window
152 */
153
154 void
155 insert_viewer_wrap(GtkWidget *menuitem, gpointer user_data)
156 {
157 guint val = 20;
158
159 insert_viewer((GtkWidget*)menuitem, (lttvwindow_viewer_constructor)user_data);
160 // selected_hook(&val);
161 }
162
163
164 /* internal functions */
165 void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor)
166 {
167 GtkMultiVPaned * multi_vpaned;
168 MainWindow * mw_data;
169 GtkWidget * viewer;
170 LttvTracesetSelector * s;
171 TimeInterval * time_interval;
172
173 mw_data = get_window_data_struct(widget);
174 if(!mw_data->current_tab) return;
175 multi_vpaned = mw_data->current_tab->multi_vpaned;
176
177 s = construct_traceset_selector(mw_data->current_tab->traceset_info->traceset);
178 viewer = (GtkWidget*)constructor(mw_data, s, "Traceset_Selector");
179 if(viewer)
180 {
181 gtk_multi_vpaned_widget_add(multi_vpaned, viewer);
182 // We unref here, because it is now referenced by the multi_vpaned!
183 g_object_unref(G_OBJECT(viewer));
184
185 // The viewer will show itself when it receives a show notify
186 // So we call the show notify hooks here. It will
187 // typically add hooks for reading, we call process trace, and the
188 // end of reading hook will call gtk_widget_show and unregister the
189 // hooks.
190 // Note that show notify gets the time_requested through the call_data.
191 //show_viewer(mw_data);
192 // in expose now call_pending_read_hooks(mw_data);
193 }
194 }
195
196
197 /* get_label function is used to get user input, it displays an input
198 * box, which allows user to input a string
199 */
200
201 void get_label_string (GtkWidget * text, gchar * label)
202 {
203 GtkEntry * entry = (GtkEntry*)text;
204 if(strlen(gtk_entry_get_text(entry))!=0)
205 strcpy(label,gtk_entry_get_text(entry));
206 }
207
208 gboolean get_label(MainWindow * mw, gchar * str, gchar* dialogue_title, gchar * label_str)
209 {
210 GtkWidget * dialogue;
211 GtkWidget * text;
212 GtkWidget * label;
213 gint id;
214
215 dialogue = gtk_dialog_new_with_buttons(dialogue_title,NULL,
216 GTK_DIALOG_MODAL,
217 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
218 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
219 NULL);
220
221 label = gtk_label_new(label_str);
222 gtk_widget_show(label);
223
224 text = gtk_entry_new();
225 gtk_widget_show(text);
226
227 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), label,TRUE, TRUE,0);
228 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), text,FALSE, FALSE,0);
229
230 id = gtk_dialog_run(GTK_DIALOG(dialogue));
231 switch(id){
232 case GTK_RESPONSE_ACCEPT:
233 get_label_string(text,str);
234 gtk_widget_destroy(dialogue);
235 break;
236 case GTK_RESPONSE_REJECT:
237 default:
238 gtk_widget_destroy(dialogue);
239 return FALSE;
240 }
241 return TRUE;
242 }
243
244
245 /* get_window_data_struct function is actually a lookup function,
246 * given a widget which is in the tree of the main window, it will
247 * return the MainWindow data structure associated with main window
248 */
249
250 MainWindow * get_window_data_struct(GtkWidget * widget)
251 {
252 GtkWidget * mw;
253 MainWindow * mw_data;
254
255 mw = lookup_widget(widget, "MWindow");
256 if(mw == NULL){
257 g_printf("Main window does not exist\n");
258 return;
259 }
260
261 mw_data = (MainWindow *) g_object_get_data(G_OBJECT(mw),"mainWindow");
262 if(mw_data == NULL){
263 g_printf("Main window data does not exist\n");
264 return;
265 }
266 return mw_data;
267 }
268
269
270 /* create_new_window function, just constructs a new main window
271 */
272
273 void create_new_window(GtkWidget* widget, gpointer user_data, gboolean clone)
274 {
275 MainWindow * parent = get_window_data_struct(widget);
276
277 if(clone){
278 g_printf("Clone : use the same traceset\n");
279 construct_main_window(parent);
280 }else{
281 g_printf("Empty : traceset is set to NULL\n");
282 construct_main_window(NULL);
283 }
284 }
285
286
287 /* move_*_viewer functions move the selected view up/down in
288 * the current tab
289 */
290
291 void move_up_viewer(GtkWidget * widget, gpointer user_data)
292 {
293 MainWindow * mw = get_window_data_struct(widget);
294 if(!mw->current_tab) return;
295 gtk_multi_vpaned_widget_move_up(mw->current_tab->multi_vpaned);
296 }
297
298 void move_down_viewer(GtkWidget * widget, gpointer user_data)
299 {
300 MainWindow * mw = get_window_data_struct(widget);
301 if(!mw->current_tab) return;
302 gtk_multi_vpaned_widget_move_down(mw->current_tab->multi_vpaned);
303 }
304
305
306 /* delete_viewer deletes the selected viewer in the current tab
307 */
308
309 void delete_viewer(GtkWidget * widget, gpointer user_data)
310 {
311 MainWindow * mw = get_window_data_struct(widget);
312 if(!mw->current_tab) return;
313 gtk_multi_vpaned_widget_delete(mw->current_tab->multi_vpaned);
314 }
315
316
317 /* open_traceset will open a traceset saved in a file
318 * Right now, it is not finished yet, (not working)
319 * FIXME
320 */
321
322 void open_traceset(GtkWidget * widget, gpointer user_data)
323 {
324 char ** dir;
325 gint id;
326 LttvTraceset * traceset;
327 MainWindow * mw_data = get_window_data_struct(widget);
328 GtkFileSelection * file_selector =
329 (GtkFileSelection *)gtk_file_selection_new("Select a traceset");
330
331 gtk_file_selection_hide_fileop_buttons(file_selector);
332
333 id = gtk_dialog_run(GTK_DIALOG(file_selector));
334 switch(id){
335 case GTK_RESPONSE_ACCEPT:
336 case GTK_RESPONSE_OK:
337 dir = gtk_file_selection_get_selections (file_selector);
338 traceset = lttv_traceset_load(dir[0]);
339 g_printf("Open a trace set %s\n", dir[0]);
340 //Not finished yet
341 g_strfreev(dir);
342 case GTK_RESPONSE_REJECT:
343 case GTK_RESPONSE_CANCEL:
344 default:
345 gtk_widget_destroy((GtkWidget*)file_selector);
346 break;
347 }
348
349 }
350
351
352 /* get_max_event_number returns the event number limit used by
353 * lttv_process_traceset(LttvTracesetContext, endTime, maxNumEvents)
354 * each viewer can set the limit
355 */
356
357 unsigned get_max_event_number(MainWindow * mw_data)
358 {
359 unsigned nb = 0, *size;
360 GtkWidget * w;
361
362 w = gtk_multi_vpaned_get_first_widget(mw_data->current_tab->multi_vpaned);
363 while(w){
364 size = (unsigned*)g_object_get_data(G_OBJECT(w), MAX_NUMBER_EVENT);
365 if(size == NULL){
366 nb = G_MAXULONG;
367 break;
368 }else{
369 if(nb < *size)
370 nb = *size;
371 }
372 w = gtk_multi_vpaned_get_next_widget(mw_data->current_tab->multi_vpaned);
373 }
374 return nb;
375 }
376
377
378 /* call_pending_read_hooks parses the traceset first by calling
379 * process_traceset, then display all viewers of
380 * the current tab
381 * It will then remove all entries from the time_requests array.
382 * CHECK : we give more events than requested to the viewers. They
383 * Have to filter them by themselves.
384 */
385
386 gint compare_time_request(TimeRequest *a, TimeRequest *b)
387 {
388 return ltt_time_compare(a->time_window.start_time, b->time_window.start_time);
389 }
390
391 void call_pending_read_hooks(MainWindow * mw_data)
392 {
393 unsigned max_nb_events;
394 GdkWindow * win;
395 GdkCursor * new;
396 GtkWidget* widget;
397 int i;
398 LttvTracesetContext *tsc;
399
400 /* Current tab check : if no current tab is present, no hooks to call. */
401 /* It makes the expose works.. */
402 if(mw_data->current_tab == NULL)
403 return;
404
405 if(mw_data->current_tab->time_requests->len == 0)
406 return;
407
408 LttvHooks *tmp_hooks = lttv_hooks_new();
409
410 tsc =
411 LTTV_TRACESET_CONTEXT(mw_data->current_tab->traceset_info->
412 traceset_context);
413
414 //set the cursor to be X shape, indicating that the computer is busy in doing its job
415 new = gdk_cursor_new(GDK_X_CURSOR);
416 widget = lookup_widget(mw_data->mwindow, "MToolbar1");
417 win = gtk_widget_get_parent_window(widget);
418 gdk_window_set_cursor(win, new);
419 gdk_cursor_unref(new);
420 gdk_window_stick(win);
421 gdk_window_unstick(win);
422
423
424 g_array_sort(mw_data->current_tab->time_requests,
425 (GCompareFunc)compare_time_request);
426
427
428 //update time window of each viewer, let viewer insert hooks needed by process_traceset
429 //lttvwindow_report_time_window(mw_data, time_window);
430
431 //max_nb_events = get_max_event_number(mw_data);
432
433 //call hooks to show each viewer and let them remove hooks
434 //show_viewer(mw_data);
435
436 // FIXME
437 // call process trace for each time interval
438 // Will have to be combined!
439 g_critical("SIZE time req len : %d", mw_data->current_tab->time_requests->len);
440
441 //g_assert(mw_data->current_tab->time_requests->len <= 1); //FIXME
442 /* Go through each time request. As they are already sorted by start_time,
443 * we check with the current event time if processing is needed. */
444 for(i=0; i < mw_data->current_tab->time_requests->len; i++)
445 {
446 g_critical("RUN i %d", i);
447 TimeRequest *time_request =
448 &g_array_index(mw_data->current_tab->time_requests, TimeRequest, i);
449 LttTime end_time = ltt_time_add( time_request->time_window.start_time,
450 time_request->time_window.time_width);
451
452 if(i == 0 || !(ltt_time_compare(time_request->time_window.start_time, ltt_event_time(tsc->e))<0) )
453 {
454 /* do it if first request or start_time >= last event's time */
455 lttv_process_traceset_seek_time(tsc, time_request->time_window.start_time);
456 lttv_process_traceset(tsc, end_time, time_request->num_events);
457 }
458 else
459 {
460 if(ltt_time_compare(time_request->time_window.start_time, ltt_event_time(tsc->e))<0
461 && !(ltt_time_compare(end_time, ltt_event_time(tsc->e))<0))
462 {
463 /* Continue reading from current event */
464 lttv_process_traceset(tsc, end_time, time_request->num_events);
465
466 }
467 else
468 {
469 if(ltt_time_compare(time_request->time_window.start_time, end_time) > 0)
470 {
471 /* This is a request for a minimum number of events, give
472 * more events than necessary */
473 lttv_process_traceset(tsc, end_time, time_request->num_events);
474 }
475 }
476 }
477
478 /* Call the end of process_traceset hook */
479 lttv_hooks_add(tmp_hooks,
480 time_request->after_hook,
481 time_request->after_hook_data);
482 lttv_hooks_call(tmp_hooks, time_request);
483 lttv_hooks_remove(tmp_hooks, time_request->after_hook);
484 }
485
486 /* Free the time requests */
487 g_array_free(mw_data->current_tab->time_requests, TRUE);
488 mw_data->current_tab->time_requests =
489 g_array_new(FALSE, FALSE, sizeof(TimeRequest));
490
491 mw_data->current_tab->time_request_pending = FALSE;
492
493 lttv_hooks_destroy(tmp_hooks);
494
495 //set the cursor back to normal
496 gdk_window_set_cursor(win, NULL);
497 }
498
499
500 /* add_trace_into_traceset_selector, each instance of a viewer has an associated
501 * selector (filter), when a trace is added into traceset, the selector should
502 * reflect the change. The function is used to update the selector
503 */
504
505 void add_trace_into_traceset_selector(GtkMultiVPaned * paned, LttTrace * t)
506 {
507 int j, k, m, nb_tracefile, nb_control, nb_per_cpu, nb_facility, nb_event;
508 LttvTracesetSelector * s;
509 LttvTraceSelector * trace;
510 LttvTracefileSelector * tracefile;
511 LttvEventtypeSelector * eventtype;
512 LttTracefile * tf;
513 GtkWidget * w;
514 LttFacility * fac;
515 LttEventType * et;
516
517 w = gtk_multi_vpaned_get_first_widget(paned);
518 while(w){
519 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
520
521 if(s){
522 trace = lttv_trace_selector_new(t);
523 lttv_traceset_selector_trace_add(s, trace);
524
525 nb_facility = ltt_trace_facility_number(t);
526 for(k=0;k<nb_facility;k++){
527 fac = ltt_trace_facility_get(t,k);
528 nb_event = (int) ltt_facility_eventtype_number(fac);
529 for(m=0;m<nb_event;m++){
530 et = ltt_facility_eventtype_get(fac,m);
531 eventtype = lttv_eventtype_selector_new(et);
532 lttv_trace_selector_eventtype_add(trace, eventtype);
533 }
534 }
535
536 nb_control = ltt_trace_control_tracefile_number(t);
537 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(t);
538 nb_tracefile = nb_control + nb_per_cpu;
539
540 for(j = 0 ; j < nb_tracefile ; j++) {
541 if(j < nb_control)
542 tf = ltt_trace_control_tracefile_get(t, j);
543 else
544 tf = ltt_trace_per_cpu_tracefile_get(t, j - nb_control);
545 tracefile = lttv_tracefile_selector_new(tf);
546 lttv_trace_selector_tracefile_add(trace, tracefile);
547 lttv_eventtype_selector_copy(trace, tracefile);
548 }
549 }else g_warning("Module does not support filtering\n");
550
551 w = gtk_multi_vpaned_get_next_widget(paned);
552 }
553 }
554
555
556 /* add_trace adds a trace into the current traceset. It first displays a
557 * directory selection dialogue to let user choose a trace, then recreates
558 * tracset_context, and redraws all the viewer of the current tab
559 */
560
561 void add_trace(GtkWidget * widget, gpointer user_data)
562 {
563 LttTrace *trace;
564 LttvTrace * trace_v;
565 LttvTraceset * traceset;
566 const char * dir;
567 gint id;
568 gint i;
569 MainWindow * mw_data = get_window_data_struct(widget);
570 GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
571 gtk_dir_selection_hide_fileop_buttons(file_selector);
572 if(remember_trace_dir[0] != '\0')
573 gtk_dir_selection_set_filename(file_selector, remember_trace_dir);
574
575 id = gtk_dialog_run(GTK_DIALOG(file_selector));
576 switch(id){
577 case GTK_RESPONSE_ACCEPT:
578 case GTK_RESPONSE_OK:
579 dir = gtk_dir_selection_get_dir (file_selector);
580 strncpy(remember_trace_dir, dir, PATH_LENGTH);
581 if(!dir || strlen(dir) == 0){
582 gtk_widget_destroy((GtkWidget*)file_selector);
583 break;
584 }
585 trace = ltt_trace_open(dir);
586 if(trace == NULL) g_critical("cannot open trace %s", dir);
587 trace_v = lttv_trace_new(trace);
588 traceset = mw_data->current_tab->traceset_info->traceset;
589
590 //Keep a reference to the traces so they are not freed.
591 for(i=0; i<lttv_traceset_number(traceset); i++)
592 {
593 LttvTrace * trace = lttv_traceset_get(traceset, i);
594 lttv_trace_ref(trace);
595 }
596
597 //remove state update hooks
598 lttv_state_remove_event_hooks(
599 (LttvTracesetState*)mw_data->current_tab->traceset_info->traceset_context);
600
601 lttv_context_fini(LTTV_TRACESET_CONTEXT(
602 mw_data->current_tab->traceset_info->traceset_context));
603 g_object_unref(mw_data->current_tab->traceset_info->traceset_context);
604
605
606 lttv_traceset_add(traceset, trace_v);
607
608 /* Create new context */
609 mw_data->current_tab->traceset_info->traceset_context =
610 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
611 lttv_context_init(
612 LTTV_TRACESET_CONTEXT(mw_data->current_tab->traceset_info->
613 traceset_context),
614 traceset);
615 //add state update hooks
616 lttv_state_add_event_hooks(
617 (LttvTracesetState*)mw_data->current_tab->traceset_info->traceset_context);
618 //Remove local reference to the traces.
619 for(i=0; i<lttv_traceset_number(traceset); i++)
620 {
621 LttvTrace * trace = lttv_traceset_get(traceset, i);
622 lttv_trace_unref(trace);
623 }
624
625
626 add_trace_into_traceset_selector(mw_data->current_tab->multi_vpaned, trace);
627
628 gtk_widget_destroy((GtkWidget*)file_selector);
629
630 //update current tab
631 //update_traceset(mw_data);
632
633 //get_traceset_time_span(mw_data,LTTV_TRACESET_CONTEXT(mw_data->current_tab->traceset_info->traceset_context)->Time_Span);
634 if(
635 lttv_traceset_number(mw_data->current_tab->traceset_info->traceset) == 1
636 || ltt_time_compare(mw_data->current_tab->current_time,
637 LTTV_TRACESET_CONTEXT(mw_data->current_tab->traceset_info->
638 traceset_context)->Time_Span->startTime)<0)
639 {
640 /* Set initial time if this is the first trace in the traceset */
641 mw_data->current_tab->current_time =
642 LTTV_TRACESET_CONTEXT(mw_data->current_tab->traceset_info->
643 traceset_context)->Time_Span->startTime;
644 mw_data->current_tab->time_window.start_time =
645 mw_data->current_tab->current_time;
646 mw_data->current_tab->time_window.time_width.tv_sec =
647 DEFAULT_TIME_WIDTH_S;
648 mw_data->current_tab->time_window.time_width.tv_nsec = 0;
649 }
650
651 /* Call the updatetraceset hooks */
652
653 SetTraceset(mw_data, (gpointer)traceset);
654 // in expose now call_pending_read_hooks(mw_data);
655
656 //lttvwindow_report_current_time(mw_data,&(mw_data->current_tab->current_time));
657 break;
658 case GTK_RESPONSE_REJECT:
659 case GTK_RESPONSE_CANCEL:
660 default:
661 gtk_widget_destroy((GtkWidget*)file_selector);
662 break;
663 }
664 }
665
666
667 /* remove_trace_into_traceset_selector, each instance of a viewer has an associated
668 * selector (filter), when a trace is remove from traceset, the selector should
669 * reflect the change. The function is used to update the selector
670 */
671
672 void remove_trace_from_traceset_selector(GtkMultiVPaned * paned, unsigned i)
673 {
674 LttvTracesetSelector * s;
675 LttvTraceSelector * t;
676 GtkWidget * w;
677
678 w = gtk_multi_vpaned_get_first_widget(paned);
679 while(w){
680 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
681 if(s){
682 t = lttv_traceset_selector_trace_get(s,i);
683 lttv_traceset_selector_trace_remove(s, i);
684 lttv_trace_selector_destroy(t);
685 }g_warning("Module dose not support filtering\n");
686 w = gtk_multi_vpaned_get_next_widget(paned);
687 }
688 }
689
690
691 /* remove_trace removes a trace from the current traceset if all viewers in
692 * the current tab are not interested in the trace. It first displays a
693 * dialogue, which shows all traces in the current traceset, to let user choose
694 * a trace, then it checks if all viewers unselect the trace, if it is true,
695 * it will remove the trace, recreate the traceset_contex,
696 * and redraws all the viewer of the current tab. If there is on trace in the
697 * current traceset, it will delete all viewers of the current tab
698 */
699
700 void remove_trace(GtkWidget * widget, gpointer user_data)
701 {
702 LttTrace *trace;
703 LttvTrace * trace_v;
704 LttvTraceset * traceset;
705 gint i, j, nb_trace;
706 char ** name, *remove_trace_name;
707 MainWindow * mw_data = get_window_data_struct(widget);
708 LttvTracesetSelector * s;
709 LttvTraceSelector * t;
710 GtkWidget * w;
711 gboolean selected;
712
713 nb_trace =lttv_traceset_number(mw_data->current_tab->traceset_info->traceset);
714 name = g_new(char*,nb_trace);
715 for(i = 0; i < nb_trace; i++){
716 trace_v = lttv_traceset_get(mw_data->current_tab->
717 traceset_info->traceset, i);
718 trace = lttv_trace(trace_v);
719 name[i] = ltt_trace_name(trace);
720 }
721
722 remove_trace_name = get_remove_trace(name, nb_trace);
723
724 if(remove_trace_name){
725 for(i=0; i<nb_trace; i++){
726 if(strcmp(remove_trace_name,name[i]) == 0){
727 //unselect the trace from the current viewer
728 w = gtk_multi_vpaned_get_widget(mw_data->current_tab->multi_vpaned);
729 if(w){
730 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
731 if(s){
732 t = lttv_traceset_selector_trace_get(s,i);
733 lttv_trace_selector_set_selected(t, FALSE);
734 }
735
736 //check if other viewers select the trace
737 w = gtk_multi_vpaned_get_first_widget(mw_data->current_tab->multi_vpaned);
738 while(w){
739 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
740 if(s){
741 t = lttv_traceset_selector_trace_get(s,i);
742 selected = lttv_trace_selector_get_selected(t);
743 if(selected)break;
744 }
745 w = gtk_multi_vpaned_get_next_widget(mw_data->current_tab->multi_vpaned);
746 }
747 }else selected = FALSE;
748
749 //if no viewer selects the trace, remove it
750 if(!selected){
751 remove_trace_from_traceset_selector(mw_data->current_tab->multi_vpaned, i);
752
753 traceset = mw_data->current_tab->traceset_info->traceset;
754 trace_v = lttv_traceset_get(traceset, i);
755 if(lttv_trace_get_ref_number(trace_v) <= 1)
756 ltt_trace_close(lttv_trace(trace_v));
757
758 //Keep a reference to the traces so they are not freed.
759 for(j=0; j<lttv_traceset_number(traceset); j++)
760 {
761 LttvTrace * trace = lttv_traceset_get(traceset, j);
762 lttv_trace_ref(trace);
763 }
764
765 //remove state update hooks
766 lttv_state_remove_event_hooks(
767 (LttvTracesetState*)mw_data->current_tab->traceset_info->traceset_context);
768 lttv_context_fini(LTTV_TRACESET_CONTEXT(mw_data->current_tab->traceset_info->traceset_context));
769 g_object_unref(mw_data->current_tab->traceset_info->traceset_context);
770
771
772 lttv_traceset_remove(traceset, i);
773 lttv_trace_unref(trace_v); // Remove local reference
774 if(!lttv_trace_get_ref_number(trace_v))
775 lttv_trace_destroy(trace_v);
776
777 mw_data->current_tab->traceset_info->traceset_context =
778 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
779 lttv_context_init(
780 LTTV_TRACESET_CONTEXT(mw_data->current_tab->
781 traceset_info->traceset_context),traceset);
782 //add state update hooks
783 lttv_state_add_event_hooks(
784 (LttvTracesetState*)mw_data->current_tab->traceset_info->traceset_context);
785
786 //Remove local reference to the traces.
787 for(j=0; j<lttv_traceset_number(traceset); j++)
788 {
789 LttvTrace * trace = lttv_traceset_get(traceset, j);
790 lttv_trace_unref(trace);
791 }
792
793
794 //update current tab
795 //update_traceset(mw_data);
796 if(nb_trace > 1){
797
798 SetTraceset(mw_data, (gpointer)traceset);
799 // in expose now call_pending_read_hooks(mw_data);
800
801 //lttvwindow_report_current_time(mw_data,&(mw_data->current_tab->current_time));
802 }else{
803 if(mw_data->current_tab){
804 while(mw_data->current_tab->multi_vpaned->num_children){
805 gtk_multi_vpaned_widget_delete(mw_data->current_tab->multi_vpaned);
806 }
807 }
808 }
809 }
810 break;
811 }
812 }
813 }
814
815 g_free(name);
816 }
817
818
819 /* save will save the traceset to a file
820 * Not implemented yet FIXME
821 */
822
823 void save(GtkWidget * widget, gpointer user_data)
824 {
825 g_printf("Save\n");
826 }
827
828 void save_as(GtkWidget * widget, gpointer user_data)
829 {
830 g_printf("Save as\n");
831 }
832
833
834 /* zoom will change the time_window of all the viewers of the
835 * current tab, and redisplay them. The main functionality is to
836 * determine the new time_window of the current tab
837 */
838
839 void zoom(GtkWidget * widget, double size)
840 {
841 TimeInterval *time_span;
842 TimeWindow new_time_window;
843 LttTime current_time, time_delta, time_s, time_e, time_tmp;
844 MainWindow * mw_data = get_window_data_struct(widget);
845
846 if(size == 1) return;
847
848 time_span = LTTV_TRACESET_CONTEXT(mw_data->current_tab->
849 traceset_info->traceset_context)->Time_Span;
850 new_time_window = mw_data->current_tab->time_window;
851 current_time = mw_data->current_tab->current_time;
852
853 time_delta = ltt_time_sub(time_span->endTime,time_span->startTime);
854 if(size == 0){
855 new_time_window.start_time = time_span->startTime;
856 new_time_window.time_width = time_delta;
857 }else{
858 new_time_window.time_width = ltt_time_div(new_time_window.time_width, size);
859 if(ltt_time_compare(new_time_window.time_width,time_delta) > 0)
860 { /* Case where zoom out is bigger than trace length */
861 new_time_window.start_time = time_span->startTime;
862 new_time_window.time_width = time_delta;
863 }
864 else
865 {
866 /* Center the image on the current time */
867 g_critical("update is HERE");
868 new_time_window.start_time =
869 ltt_time_sub(current_time, ltt_time_div(new_time_window.time_width, 2.0));
870 /* If on borders, don't fall off */
871 if(ltt_time_compare(new_time_window.start_time, time_span->startTime) <0)
872 {
873 new_time_window.start_time = time_span->startTime;
874 }
875 else
876 {
877 if(ltt_time_compare(
878 ltt_time_add(new_time_window.start_time, new_time_window.time_width),
879 time_span->endTime) > 0)
880 {
881 new_time_window.start_time =
882 ltt_time_sub(time_span->endTime, new_time_window.time_width);
883 }
884 }
885
886 }
887
888
889
890 //time_tmp = ltt_time_div(new_time_window.time_width, 2);
891 //if(ltt_time_compare(current_time, time_tmp) < 0){
892 // time_s = time_span->startTime;
893 //} else {
894 // time_s = ltt_time_sub(current_time,time_tmp);
895 //}
896 //time_e = ltt_time_add(current_time,time_tmp);
897 //if(ltt_time_compare(time_span->startTime, time_s) > 0){
898 // time_s = time_span->startTime;
899 //}else if(ltt_time_compare(time_span->endTime, time_e) < 0){
900 // time_e = time_span->endTime;
901 // time_s = ltt_time_sub(time_e,new_time_window.time_width);
902 //}
903 //new_time_window.start_time = time_s;
904 }
905
906 //lttvwindow_report_time_window(mw_data, &new_time_window);
907 //call_pending_read_hooks(mw_data);
908
909 //lttvwindow_report_current_time(mw_data,&(mw_data->current_tab->current_time));
910 set_time_window(mw_data, &new_time_window);
911 // in expose now call_pending_read_hooks(mw_data);
912 gtk_multi_vpaned_set_adjust(mw_data->current_tab->multi_vpaned, &new_time_window, FALSE);
913 }
914
915 void zoom_in(GtkWidget * widget, gpointer user_data)
916 {
917 zoom(widget, 2);
918 }
919
920 void zoom_out(GtkWidget * widget, gpointer user_data)
921 {
922 zoom(widget, 0.5);
923 }
924
925 void zoom_extended(GtkWidget * widget, gpointer user_data)
926 {
927 zoom(widget, 0);
928 }
929
930 void go_to_time(GtkWidget * widget, gpointer user_data)
931 {
932 g_printf("Go to time\n");
933 }
934
935 void show_time_frame(GtkWidget * widget, gpointer user_data)
936 {
937 g_printf("Show time frame\n");
938 }
939
940
941 /* callback function */
942
943 void
944 on_empty_traceset_activate (GtkMenuItem *menuitem,
945 gpointer user_data)
946 {
947 create_new_window((GtkWidget*)menuitem, user_data, FALSE);
948 }
949
950
951 void
952 on_clone_traceset_activate (GtkMenuItem *menuitem,
953 gpointer user_data)
954 {
955 create_new_window((GtkWidget*)menuitem, user_data, TRUE);
956 }
957
958
959 /* create_new_tab calls create_tab to construct a new tab in the main window
960 */
961
962 void create_new_tab(GtkWidget* widget, gpointer user_data){
963 gchar label[PATH_LENGTH];
964 MainWindow * mw_data = get_window_data_struct(widget);
965 GtkNotebook * notebook = (GtkNotebook *)lookup_widget(widget, "MNotebook");
966 if(notebook == NULL){
967 g_printf("Notebook does not exist\n");
968 return;
969 }
970
971 strcpy(label,"Page");
972 if(get_label(mw_data, label,"Get the name of the tab","Please input tab's name"))
973 create_tab (NULL, mw_data, notebook, label);
974 }
975
976 void
977 on_tab_activate (GtkMenuItem *menuitem,
978 gpointer user_data)
979 {
980 create_new_tab((GtkWidget*)menuitem, user_data);
981 }
982
983
984 void
985 on_open_activate (GtkMenuItem *menuitem,
986 gpointer user_data)
987 {
988 open_traceset((GtkWidget*)menuitem, user_data);
989 }
990
991
992 void
993 on_close_activate (GtkMenuItem *menuitem,
994 gpointer user_data)
995 {
996 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
997 main_window_destructor(mw_data);
998 }
999
1000
1001 /* remove the current tab from the main window if it is not the default tab
1002 */
1003
1004 void
1005 on_close_tab_activate (GtkMenuItem *menuitem,
1006 gpointer user_data)
1007 {
1008 GList * list;
1009 int count = 0;
1010 GtkWidget * notebook;
1011 Tab * tmp;
1012 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
1013 notebook = lookup_widget((GtkWidget*)menuitem, "MNotebook");
1014 if(notebook == NULL){
1015 g_printf("Notebook does not exist\n");
1016 return;
1017 }
1018
1019 if(mw_data->tab == mw_data->current_tab){
1020 // tmp = mw_data->current_tb;
1021 // mw_data->tab = mw_data->current_tab->next;
1022 g_printf("The default TAB can not be deleted\n");
1023 return;
1024 }else{
1025 tmp = mw_data->tab;
1026 while(tmp != mw_data->current_tab){
1027 tmp = tmp->next;
1028 count++;
1029 }
1030 }
1031
1032 gtk_notebook_remove_page((GtkNotebook*)notebook, count);
1033 list = gtk_container_get_children(GTK_CONTAINER(notebook));
1034 if(g_list_length(list)==1)
1035 gtk_notebook_set_show_tabs((GtkNotebook*)notebook, FALSE);
1036 }
1037
1038
1039 void
1040 on_add_trace_activate (GtkMenuItem *menuitem,
1041 gpointer user_data)
1042 {
1043 add_trace((GtkWidget*)menuitem, user_data);
1044 }
1045
1046
1047 void
1048 on_remove_trace_activate (GtkMenuItem *menuitem,
1049 gpointer user_data)
1050 {
1051 remove_trace((GtkWidget*)menuitem, user_data);
1052 }
1053
1054
1055 void
1056 on_save_activate (GtkMenuItem *menuitem,
1057 gpointer user_data)
1058 {
1059 save((GtkWidget*)menuitem, user_data);
1060 }
1061
1062
1063 void
1064 on_save_as_activate (GtkMenuItem *menuitem,
1065 gpointer user_data)
1066 {
1067 save_as((GtkWidget*)menuitem, user_data);
1068 }
1069
1070
1071 void
1072 on_quit_activate (GtkMenuItem *menuitem,
1073 gpointer user_data)
1074 {
1075 gtk_main_quit ();
1076 }
1077
1078
1079 void
1080 on_cut_activate (GtkMenuItem *menuitem,
1081 gpointer user_data)
1082 {
1083 g_printf("Cut\n");
1084 }
1085
1086
1087 void
1088 on_copy_activate (GtkMenuItem *menuitem,
1089 gpointer user_data)
1090 {
1091 g_printf("Copye\n");
1092 }
1093
1094
1095 void
1096 on_paste_activate (GtkMenuItem *menuitem,
1097 gpointer user_data)
1098 {
1099 g_printf("Paste\n");
1100 }
1101
1102
1103 void
1104 on_delete_activate (GtkMenuItem *menuitem,
1105 gpointer user_data)
1106 {
1107 g_printf("Delete\n");
1108 }
1109
1110
1111 void
1112 on_zoom_in_activate (GtkMenuItem *menuitem,
1113 gpointer user_data)
1114 {
1115 zoom_in((GtkWidget*)menuitem, user_data);
1116 }
1117
1118
1119 void
1120 on_zoom_out_activate (GtkMenuItem *menuitem,
1121 gpointer user_data)
1122 {
1123 zoom_out((GtkWidget*)menuitem, user_data);
1124 }
1125
1126
1127 void
1128 on_zoom_extended_activate (GtkMenuItem *menuitem,
1129 gpointer user_data)
1130 {
1131 zoom_extended((GtkWidget*)menuitem, user_data);
1132 }
1133
1134
1135 void
1136 on_go_to_time_activate (GtkMenuItem *menuitem,
1137 gpointer user_data)
1138 {
1139 go_to_time((GtkWidget*)menuitem, user_data);
1140 }
1141
1142
1143 void
1144 on_show_time_frame_activate (GtkMenuItem *menuitem,
1145 gpointer user_data)
1146 {
1147 show_time_frame((GtkWidget*)menuitem, user_data);
1148 }
1149
1150
1151 void
1152 on_move_viewer_up_activate (GtkMenuItem *menuitem,
1153 gpointer user_data)
1154 {
1155 move_up_viewer((GtkWidget*)menuitem, user_data);
1156 }
1157
1158
1159 void
1160 on_move_viewer_down_activate (GtkMenuItem *menuitem,
1161 gpointer user_data)
1162 {
1163 move_down_viewer((GtkWidget*)menuitem, user_data);
1164 }
1165
1166
1167 void
1168 on_remove_viewer_activate (GtkMenuItem *menuitem,
1169 gpointer user_data)
1170 {
1171 delete_viewer((GtkWidget*)menuitem, user_data);
1172 }
1173
1174 void
1175 on_trace_filter_activate (GtkMenuItem *menuitem,
1176 gpointer user_data)
1177 {
1178 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
1179 LttvTracesetSelector * s;
1180 GtkWidget * w = gtk_multi_vpaned_get_widget(mw_data->current_tab->multi_vpaned);
1181
1182 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1183 if(!s){
1184 g_printf("There is no viewer yet\n");
1185 return;
1186 }
1187 if(get_filter_selection(s, "Configure trace and tracefile filter", "Select traces and tracefiles")){
1188 //FIXME report filter change
1189 //update_traceset(mw_data);
1190 //call_pending_read_hooks(mw_data);
1191 //lttvwindow_report_current_time(mw_data,&(mw_data->current_tab->current_time));
1192 }
1193 }
1194
1195 void
1196 on_trace_facility_activate (GtkMenuItem *menuitem,
1197 gpointer user_data)
1198 {
1199 g_printf("Trace facility selector: %s\n");
1200 }
1201
1202
1203 /* Dispaly a file selection dialogue to let user select a module, then call
1204 * lttv_module_load(), finally insert tool button and menu entry in the main window
1205 * for the loaded module
1206 */
1207
1208 void
1209 on_load_module_activate (GtkMenuItem *menuitem,
1210 gpointer user_data)
1211 {
1212 char ** dir;
1213 gint id;
1214 char str[PATH_LENGTH], *str1;
1215 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
1216 GtkFileSelection * file_selector = (GtkFileSelection *)gtk_file_selection_new("Select a module");
1217 if(remember_plugins_dir[0] != '\0')
1218 gtk_file_selection_set_filename(file_selector, remember_plugins_dir);
1219 gtk_file_selection_hide_fileop_buttons(file_selector);
1220
1221 str[0] = '\0';
1222 id = gtk_dialog_run(GTK_DIALOG(file_selector));
1223 switch(id){
1224 case GTK_RESPONSE_ACCEPT:
1225 case GTK_RESPONSE_OK:
1226 dir = gtk_file_selection_get_selections (file_selector);
1227 strncpy(str,dir[0],PATH_LENGTH);
1228 strncpy(remember_plugins_dir,dir[0],PATH_LENGTH);
1229 str1 = strrchr(str,'/');
1230 if(str1)str1++;
1231 else{
1232 str1 = strrchr(str,'\\');
1233 str1++;
1234 }
1235 lttv_module_require(str1, NULL);
1236 g_strfreev(dir);
1237 case GTK_RESPONSE_REJECT:
1238 case GTK_RESPONSE_CANCEL:
1239 default:
1240 gtk_widget_destroy((GtkWidget*)file_selector);
1241 break;
1242 }
1243 g_printf("Load module: %s\n", str);
1244 }
1245
1246
1247 /* Display all loaded modules, let user to select a module to unload
1248 * by calling lttv_module_unload
1249 */
1250
1251 void
1252 on_unload_module_activate (GtkMenuItem *menuitem,
1253 gpointer user_data)
1254 {
1255 int i;
1256 GPtrArray *name;
1257 char *unload_module_name;
1258 guint nb;
1259 LttvLibrary *library;
1260 LttvLibraryInfo library_info;
1261 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
1262
1263 name = g_ptr_array_new();
1264 nb = lttv_library_number();
1265
1266 for(i=0;i<nb;i++){
1267 library = lttv_library_get(i);
1268 lttv_library_info(library, &library_info);
1269 if(library_info.load_count > 0) g_ptr_array_add(name, library_info.name);
1270 }
1271
1272 unload_module_name =get_unload_module((char **)(name->pdata), name->len);
1273
1274 if(unload_module_name){
1275 for(i=0;i<nb;i++){
1276 library = lttv_library_get(i);
1277 lttv_library_info(library, &library_info);
1278 if(strcmp(unload_module_name, library_info.name) == 0){
1279 lttv_library_unload(library);
1280 break;
1281 }
1282 }
1283 }
1284
1285 g_ptr_array_free(name, TRUE);
1286 }
1287
1288
1289 /* Display a directory dialogue to let user select a path for module searching
1290 */
1291
1292 void
1293 on_add_module_search_path_activate (GtkMenuItem *menuitem,
1294 gpointer user_data)
1295 {
1296 GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select module path");
1297 const char * dir;
1298 gint id;
1299
1300 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
1301 if(remember_plugins_dir[0] != '\0')
1302 gtk_dir_selection_set_filename(file_selector, remember_plugins_dir);
1303
1304 id = gtk_dialog_run(GTK_DIALOG(file_selector));
1305 switch(id){
1306 case GTK_RESPONSE_ACCEPT:
1307 case GTK_RESPONSE_OK:
1308 dir = gtk_dir_selection_get_dir (file_selector);
1309 strncpy(remember_plugins_dir,dir,PATH_LENGTH);
1310 strncat(remember_plugins_dir,"/",PATH_LENGTH);
1311 lttv_library_path_add(dir);
1312 case GTK_RESPONSE_REJECT:
1313 case GTK_RESPONSE_CANCEL:
1314 default:
1315 gtk_widget_destroy((GtkWidget*)file_selector);
1316 break;
1317 }
1318 }
1319
1320
1321 void
1322 on_color_activate (GtkMenuItem *menuitem,
1323 gpointer user_data)
1324 {
1325 g_printf("Color\n");
1326 }
1327
1328
1329 void
1330 on_filter_activate (GtkMenuItem *menuitem,
1331 gpointer user_data)
1332 {
1333 g_printf("Filter\n");
1334 }
1335
1336
1337 void
1338 on_save_configuration_activate (GtkMenuItem *menuitem,
1339 gpointer user_data)
1340 {
1341 g_printf("Save configuration\n");
1342 }
1343
1344
1345 void
1346 on_content_activate (GtkMenuItem *menuitem,
1347 gpointer user_data)
1348 {
1349 g_printf("Content\n");
1350 }
1351
1352
1353 void
1354 on_about_activate (GtkMenuItem *menuitem,
1355 gpointer user_data)
1356 {
1357 g_printf("About...\n");
1358 }
1359
1360
1361 void
1362 on_button_new_clicked (GtkButton *button,
1363 gpointer user_data)
1364 {
1365 create_new_window((GtkWidget*)button, user_data, TRUE);
1366 }
1367
1368 void
1369 on_button_new_tab_clicked (GtkButton *button,
1370 gpointer user_data)
1371 {
1372 create_new_tab((GtkWidget*)button, user_data);
1373 }
1374
1375 void
1376 on_button_open_clicked (GtkButton *button,
1377 gpointer user_data)
1378 {
1379 open_traceset((GtkWidget*)button, user_data);
1380 }
1381
1382
1383 void
1384 on_button_add_trace_clicked (GtkButton *button,
1385 gpointer user_data)
1386 {
1387 add_trace((GtkWidget*)button, user_data);
1388 }
1389
1390
1391 void
1392 on_button_remove_trace_clicked (GtkButton *button,
1393 gpointer user_data)
1394 {
1395 remove_trace((GtkWidget*)button, user_data);
1396 }
1397
1398
1399 void
1400 on_button_save_clicked (GtkButton *button,
1401 gpointer user_data)
1402 {
1403 save((GtkWidget*)button, user_data);
1404 }
1405
1406
1407 void
1408 on_button_save_as_clicked (GtkButton *button,
1409 gpointer user_data)
1410 {
1411 save_as((GtkWidget*)button, user_data);
1412 }
1413
1414
1415 void
1416 on_button_zoom_in_clicked (GtkButton *button,
1417 gpointer user_data)
1418 {
1419 zoom_in((GtkWidget*)button, user_data);
1420 }
1421
1422
1423 void
1424 on_button_zoom_out_clicked (GtkButton *button,
1425 gpointer user_data)
1426 {
1427 zoom_out((GtkWidget*)button, user_data);
1428 }
1429
1430
1431 void
1432 on_button_zoom_extended_clicked (GtkButton *button,
1433 gpointer user_data)
1434 {
1435 zoom_extended((GtkWidget*)button, user_data);
1436 }
1437
1438
1439 void
1440 on_button_go_to_time_clicked (GtkButton *button,
1441 gpointer user_data)
1442 {
1443 go_to_time((GtkWidget*)button, user_data);
1444 }
1445
1446
1447 void
1448 on_button_show_time_frame_clicked (GtkButton *button,
1449 gpointer user_data)
1450 {
1451 show_time_frame((GtkWidget*)button, user_data);
1452 }
1453
1454
1455 void
1456 on_button_move_up_clicked (GtkButton *button,
1457 gpointer user_data)
1458 {
1459 move_up_viewer((GtkWidget*)button, user_data);
1460 }
1461
1462
1463 void
1464 on_button_move_down_clicked (GtkButton *button,
1465 gpointer user_data)
1466 {
1467 move_down_viewer((GtkWidget*)button, user_data);
1468 }
1469
1470
1471 void
1472 on_button_delete_viewer_clicked (GtkButton *button,
1473 gpointer user_data)
1474 {
1475 delete_viewer((GtkWidget*)button, user_data);
1476 }
1477
1478 void
1479 on_MWindow_destroy (GtkObject *object,
1480 gpointer user_data)
1481 {
1482 MainWindow *main_window = get_window_data_struct((GtkWidget*)object);
1483 GtkWidget *widget;
1484 Tab *tab = main_window->tab;
1485 LttvIAttribute *attributes = main_window->attributes;
1486 LttvAttributeValue value;
1487
1488 //This is unnecessary, since widgets will be destroyed
1489 //by the main window widget anyway.
1490 //remove_all_menu_toolbar_constructors(main_window, NULL);
1491
1492 g_assert(lttv_iattribute_find_by_path(attributes,
1493 "viewers/menu", LTTV_POINTER, &value));
1494 lttv_menus_destroy((LttvMenus*)*(value.v_pointer));
1495
1496 g_assert(lttv_iattribute_find_by_path(attributes_global,
1497 "viewers/toolbar", LTTV_POINTER, &value));
1498 lttv_toolbars_destroy((LttvToolbars*)*(value.v_pointer));
1499
1500 while(main_window->tab){
1501 lttv_state_remove_event_hooks(
1502 (LttvTracesetState*)main_window->tab->traceset_info->traceset_context);
1503 main_window->tab = main_window->tab->next;
1504 }
1505 g_object_unref(main_window->attributes);
1506 g_main_window_list = g_slist_remove(g_main_window_list, main_window);
1507
1508 g_win_count--;
1509 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list));
1510 if(g_win_count == 0)
1511 gtk_main_quit ();
1512 }
1513
1514 gboolean
1515 on_MWindow_configure (GtkWidget *widget,
1516 GdkEventConfigure *event,
1517 gpointer user_data)
1518 {
1519 MainWindow * mw_data = get_window_data_struct((GtkWidget*)widget);
1520 float width = event->width;
1521 Tab * tab = mw_data->tab;
1522 TimeWindow time_win;
1523 double ratio;
1524 TimeInterval *time_span;
1525 LttTime time;
1526
1527 // MD : removed time width modification upon resizing of the main window.
1528 // The viewers will redraw themselves completely, without time interval
1529 // modification.
1530 /* while(tab){
1531 if(mw_data->window_width){
1532 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
1533 time_win = tab->time_window;
1534 ratio = width / mw_data->window_width;
1535 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
1536 time = ltt_time_sub(time_span->endTime, time_win.start_time);
1537 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
1538 tab->time_window.time_width = time;
1539 }
1540 }
1541 tab = tab->next;
1542 }
1543
1544 mw_data->window_width = (int)width;
1545 */
1546 return FALSE;
1547 }
1548
1549 /* Set current tab
1550 */
1551
1552 void
1553 on_MNotebook_switch_page (GtkNotebook *notebook,
1554 GtkNotebookPage *page,
1555 guint page_num,
1556 gpointer user_data)
1557 {
1558 MainWindow * mw = get_window_data_struct((GtkWidget*)notebook);
1559 Tab * tab = mw->tab;
1560
1561 while(page_num){
1562 tab = tab->next;
1563 page_num--;
1564 }
1565 mw->current_tab = tab;
1566 }
1567
1568
1569 /* callback function to check or uncheck the check box (filter)
1570 */
1571
1572 void checkbox_changed(GtkTreeView *treeview,
1573 GtkTreePath *arg1,
1574 GtkTreeViewColumn *arg2,
1575 gpointer user_data)
1576 {
1577 GtkTreeStore * store = (GtkTreeStore *)gtk_tree_view_get_model (treeview);
1578 GtkTreeIter iter;
1579 gboolean value;
1580
1581 if (gtk_tree_model_get_iter ((GtkTreeModel *)store, &iter, arg1)){
1582 gtk_tree_model_get ((GtkTreeModel *)store, &iter, CHECKBOX_COLUMN, &value, -1);
1583 value = value? FALSE : TRUE;
1584 gtk_tree_store_set (GTK_TREE_STORE (store), &iter, CHECKBOX_COLUMN, value, -1);
1585 }
1586
1587 }
1588
1589
1590 /* According to user's selection, update selector(filter)
1591 */
1592
1593 void update_filter(LttvTracesetSelector *s, GtkTreeStore *store )
1594 {
1595 GtkTreeIter iter, child_iter, child_iter1, child_iter2;
1596 int i, j, k, nb_eventtype;
1597 LttvTraceSelector * trace;
1598 LttvTracefileSelector * tracefile;
1599 LttvEventtypeSelector * eventtype;
1600 gboolean value, value1, value2;
1601
1602 if(gtk_tree_model_get_iter_first((GtkTreeModel*)store, &iter)){
1603 i = 0;
1604 do{
1605 trace = lttv_traceset_selector_trace_get(s, i);
1606 nb_eventtype = lttv_trace_selector_eventtype_number(trace);
1607 gtk_tree_model_get ((GtkTreeModel*)store, &iter, CHECKBOX_COLUMN, &value,-1);
1608 if(value){
1609 j = 0;
1610 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter, &iter)){
1611 do{
1612 if(j<1){//eventtype selector for trace
1613 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter, CHECKBOX_COLUMN, &value2,-1);
1614 if(value2){
1615 k=0;
1616 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter1, &child_iter)){
1617 do{
1618 eventtype = lttv_trace_selector_eventtype_get(trace,k);
1619 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter1, CHECKBOX_COLUMN, &value2,-1);
1620 lttv_eventtype_selector_set_selected(eventtype,value2);
1621 k++;
1622 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter1));
1623 }
1624 }
1625 }else{ //tracefile selector
1626 tracefile = lttv_trace_selector_tracefile_get(trace, j - 1);
1627 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter, CHECKBOX_COLUMN, &value1,-1);
1628 lttv_tracefile_selector_set_selected(tracefile,value1);
1629 if(value1){
1630 gtk_tree_model_iter_children((GtkTreeModel*)store, &child_iter1, &child_iter); //eventtype selector
1631 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter1, CHECKBOX_COLUMN, &value2,-1);
1632 if(value2){
1633 k = 0;
1634 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter2, &child_iter1)){
1635 do{//eventtype selector for tracefile
1636 eventtype = lttv_tracefile_selector_eventtype_get(tracefile,k);
1637 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter2, CHECKBOX_COLUMN, &value2,-1);
1638 lttv_eventtype_selector_set_selected(eventtype,value2);
1639 k++;
1640 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter2));
1641 }
1642 }
1643 }
1644 }
1645 j++;
1646 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter));
1647 }
1648 }
1649 lttv_trace_selector_set_selected(trace,value);
1650 i++;
1651 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &iter));
1652 }
1653 }
1654
1655
1656 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
1657 * eventtypes, tracefiles and traces (filter)
1658 */
1659
1660 gboolean get_filter_selection(LttvTracesetSelector *s,char *title, char * column_title)
1661 {
1662 GtkWidget * dialogue;
1663 GtkTreeStore * store;
1664 GtkWidget * tree;
1665 GtkWidget * scroll_win;
1666 GtkCellRenderer * renderer;
1667 GtkTreeViewColumn * column;
1668 GtkTreeIter iter, child_iter, child_iter1, child_iter2;
1669 int i, j, k, id, nb_trace, nb_tracefile, nb_eventtype;
1670 LttvTraceSelector * trace;
1671 LttvTracefileSelector * tracefile;
1672 LttvEventtypeSelector * eventtype;
1673 char * name;
1674 gboolean checked;
1675
1676 dialogue = gtk_dialog_new_with_buttons(title,
1677 NULL,
1678 GTK_DIALOG_MODAL,
1679 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
1680 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
1681 NULL);
1682 gtk_window_set_default_size((GtkWindow*)dialogue, 300, 500);
1683
1684 store = gtk_tree_store_new (TOTAL_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING);
1685 tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
1686 g_object_unref (G_OBJECT (store));
1687 g_signal_connect (G_OBJECT (tree), "row-activated",
1688 G_CALLBACK (checkbox_changed),
1689 NULL);
1690
1691
1692 renderer = gtk_cell_renderer_toggle_new ();
1693 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle *)renderer, FALSE);
1694
1695 g_object_set (G_OBJECT (renderer),"activatable", TRUE, NULL);
1696
1697 column = gtk_tree_view_column_new_with_attributes ("Checkbox",
1698 renderer,
1699 "active", CHECKBOX_COLUMN,
1700 NULL);
1701 gtk_tree_view_column_set_alignment (column, 0.5);
1702 gtk_tree_view_column_set_fixed_width (column, 20);
1703 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
1704
1705 renderer = gtk_cell_renderer_text_new ();
1706 column = gtk_tree_view_column_new_with_attributes (column_title,
1707 renderer,
1708 "text", NAME_COLUMN,
1709 NULL);
1710 gtk_tree_view_column_set_alignment (column, 0.0);
1711 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
1712 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree), FALSE);
1713
1714 scroll_win = gtk_scrolled_window_new (NULL, NULL);
1715 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
1716 GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
1717 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
1718
1719 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
1720
1721 gtk_widget_show(scroll_win);
1722 gtk_widget_show(tree);
1723
1724 nb_trace = lttv_traceset_selector_trace_number(s);
1725 for(i=0;i<nb_trace;i++){
1726 trace = lttv_traceset_selector_trace_get(s, i);
1727 name = lttv_trace_selector_get_name(trace);
1728 gtk_tree_store_append (store, &iter, NULL);
1729 checked = lttv_trace_selector_get_selected(trace);
1730 gtk_tree_store_set (store, &iter,
1731 CHECKBOX_COLUMN,checked,
1732 NAME_COLUMN,name,
1733 -1);
1734
1735 gtk_tree_store_append (store, &child_iter, &iter);
1736 gtk_tree_store_set (store, &child_iter,
1737 CHECKBOX_COLUMN, checked,
1738 NAME_COLUMN,"eventtype",
1739 -1);
1740
1741 nb_eventtype = lttv_trace_selector_eventtype_number(trace);
1742 for(j=0;j<nb_eventtype;j++){
1743 eventtype = lttv_trace_selector_eventtype_get(trace,j);
1744 name = lttv_eventtype_selector_get_name(eventtype);
1745 checked = lttv_eventtype_selector_get_selected(eventtype);
1746 gtk_tree_store_append (store, &child_iter1, &child_iter);
1747 gtk_tree_store_set (store, &child_iter1,
1748 CHECKBOX_COLUMN, checked,
1749 NAME_COLUMN,name,
1750 -1);
1751 }
1752
1753 nb_tracefile = lttv_trace_selector_tracefile_number(trace);
1754 for(j=0;j<nb_tracefile;j++){
1755 tracefile = lttv_trace_selector_tracefile_get(trace, j);
1756 name = lttv_tracefile_selector_get_name(tracefile);
1757 gtk_tree_store_append (store, &child_iter, &iter);
1758 checked = lttv_tracefile_selector_get_selected(tracefile);
1759 gtk_tree_store_set (store, &child_iter,
1760 CHECKBOX_COLUMN, checked,
1761 NAME_COLUMN,name,
1762 -1);
1763
1764 gtk_tree_store_append (store, &child_iter1, &child_iter);
1765 gtk_tree_store_set (store, &child_iter1,
1766 CHECKBOX_COLUMN, checked,
1767 NAME_COLUMN,"eventtype",
1768 -1);
1769
1770 for(k=0;k<nb_eventtype;k++){
1771 eventtype = lttv_tracefile_selector_eventtype_get(tracefile,k);
1772 name = lttv_eventtype_selector_get_name(eventtype);
1773 checked = lttv_eventtype_selector_get_selected(eventtype);
1774 gtk_tree_store_append (store, &child_iter2, &child_iter1);
1775 gtk_tree_store_set (store, &child_iter2,
1776 CHECKBOX_COLUMN, checked,
1777 NAME_COLUMN,name,
1778 -1);
1779 }
1780 }
1781 }
1782
1783 id = gtk_dialog_run(GTK_DIALOG(dialogue));
1784 switch(id){
1785 case GTK_RESPONSE_ACCEPT:
1786 case GTK_RESPONSE_OK:
1787 update_filter(s, store);
1788 gtk_widget_destroy(dialogue);
1789 return TRUE;
1790 case GTK_RESPONSE_REJECT:
1791 case GTK_RESPONSE_CANCEL:
1792 default:
1793 gtk_widget_destroy(dialogue);
1794 break;
1795 }
1796 return FALSE;
1797 }
1798
1799
1800 /* Select a trace which will be removed from traceset
1801 */
1802
1803 char * get_remove_trace(char ** all_trace_name, int nb_trace)
1804 {
1805 return get_selection(all_trace_name, nb_trace,
1806 "Select a trace", "Trace pathname");
1807 }
1808
1809
1810 /* Select a module which will be unloaded
1811 */
1812
1813 char * get_unload_module(char ** loaded_module_name, int nb_module)
1814 {
1815 return get_selection(loaded_module_name, nb_module,
1816 "Select an unload module", "Module pathname");
1817 }
1818
1819
1820 /* Display a dialogue which shows all selectable items, let user to
1821 * select one of them
1822 */
1823
1824 char * get_selection(char ** loaded_module_name, int nb_module,
1825 char *title, char * column_title)
1826 {
1827 GtkWidget * dialogue;
1828 GtkWidget * scroll_win;
1829 GtkWidget * tree;
1830 GtkListStore * store;
1831 GtkTreeViewColumn * column;
1832 GtkCellRenderer * renderer;
1833 GtkTreeSelection * select;
1834 GtkTreeIter iter;
1835 gint id, i;
1836 char * unload_module_name = NULL;
1837
1838 dialogue = gtk_dialog_new_with_buttons(title,
1839 NULL,
1840 GTK_DIALOG_MODAL,
1841 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
1842 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
1843 NULL);
1844 gtk_window_set_default_size((GtkWindow*)dialogue, 500, 200);
1845
1846 scroll_win = gtk_scrolled_window_new (NULL, NULL);
1847 gtk_widget_show ( scroll_win);
1848 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
1849 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1850
1851 store = gtk_list_store_new (N_COLUMNS,G_TYPE_STRING);
1852 tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL (store));
1853 gtk_widget_show ( tree);
1854 g_object_unref (G_OBJECT (store));
1855
1856 renderer = gtk_cell_renderer_text_new ();
1857 column = gtk_tree_view_column_new_with_attributes (column_title,
1858 renderer,
1859 "text", MODULE_COLUMN,
1860 NULL);
1861 gtk_tree_view_column_set_alignment (column, 0.5);
1862 gtk_tree_view_column_set_fixed_width (column, 150);
1863 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
1864
1865 select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
1866 gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
1867
1868 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
1869
1870 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
1871
1872 for(i=0;i<nb_module;i++){
1873 gtk_list_store_append (store, &iter);
1874 gtk_list_store_set (store, &iter, MODULE_COLUMN,loaded_module_name[i],-1);
1875 }
1876
1877 id = gtk_dialog_run(GTK_DIALOG(dialogue));
1878 switch(id){
1879 case GTK_RESPONSE_ACCEPT:
1880 case GTK_RESPONSE_OK:
1881 if (gtk_tree_selection_get_selected (select, (GtkTreeModel**)&store, &iter)){
1882 gtk_tree_model_get ((GtkTreeModel*)store, &iter, MODULE_COLUMN, &unload_module_name, -1);
1883 }
1884 case GTK_RESPONSE_REJECT:
1885 case GTK_RESPONSE_CANCEL:
1886 default:
1887 gtk_widget_destroy(dialogue);
1888 break;
1889 }
1890
1891 return unload_module_name;
1892 }
1893
1894
1895 /* Insert all menu entry and tool buttons into this main window
1896 * for modules.
1897 *
1898 */
1899
1900 void add_all_menu_toolbar_constructors(MainWindow * mw, gpointer user_data)
1901 {
1902 int i;
1903 GdkPixbuf *pixbuf;
1904 lttvwindow_viewer_constructor constructor;
1905 LttvMenus * global_menu, * instance_menu;
1906 LttvToolbars * global_toolbar, * instance_toolbar;
1907 LttvMenuClosure *menu_item;
1908 LttvToolbarClosure *toolbar_item;
1909 LttvAttributeValue value;
1910 LttvIAttribute *global_attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
1911 LttvIAttribute *attributes = LTTV_IATTRIBUTES(mw->attributes);
1912 GtkWidget * tool_menu_title_menu, *new_widget, *pixmap;
1913
1914 g_assert(lttv_iattribute_find_by_path(global_attributes,
1915 "viewers/menu", LTTV_POINTER, &value));
1916 if(*(value.v_pointer) == NULL)
1917 (LttvMenus*)*(value.v_pointer) = lttv_menus_new();
1918 global_menu = (LttvMenus*)*(value.v_pointer);
1919
1920 g_assert(lttv_iattribute_find_by_path(attributes,
1921 "viewers/menu", LTTV_POINTER, &value));
1922 if(*(value.v_pointer) == NULL)
1923 (LttvMenus*)*(value.v_pointer) = lttv_menus_new();
1924 instance_menu = (LttvMenus*)*(value.v_pointer);
1925
1926
1927
1928 g_assert(lttv_iattribute_find_by_path(global_attributes,
1929 "viewers/toolbar", LTTV_POINTER, &value));
1930 if(*(value.v_pointer) == NULL)
1931 (LttvToolbars*)*(value.v_pointer) = lttv_toolbars_new();
1932 global_toolbar = (LttvToolbars*)*(value.v_pointer);
1933
1934 g_assert(lttv_iattribute_find_by_path(attributes,
1935 "viewers/toolbar", LTTV_POINTER, &value));
1936 if(*(value.v_pointer) == NULL)
1937 (LttvToolbars*)*(value.v_pointer) = lttv_toolbars_new();
1938 instance_toolbar = (LttvToolbars*)*(value.v_pointer);
1939
1940 /* Add missing menu entries to window instance */
1941 for(i=0;i<global_menu->len;i++) {
1942 menu_item = &g_array_index(global_menu, LttvMenuClosure, i);
1943
1944 //add menu_item to window instance;
1945 constructor = menu_item->con;
1946 tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
1947 new_widget =
1948 gtk_menu_item_new_with_mnemonic (menu_item->menuText);
1949 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu),
1950 new_widget);
1951 g_signal_connect ((gpointer) new_widget, "activate",
1952 G_CALLBACK (insert_viewer_wrap),
1953 constructor);
1954 gtk_widget_show (new_widget);
1955 lttv_menus_add(instance_menu, menu_item->con,
1956 menu_item->menu_path,
1957 menu_item->menu_text,
1958 new_widget);
1959
1960 }
1961
1962 /* Add missing toolbar entries to window instance */
1963 for(i=0;i<global_toolbar->len;i++) {
1964 toolbar_item = &g_array_index(global_toolbar, LttvToolbarClosure, i);
1965
1966 //add toolbar_item to window instance;
1967 constructor = toolbar_item->con;
1968 tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1");
1969 pixbuf = gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item->pixmap);
1970 pixmap = gtk_image_new_from_pixbuf(pixbuf);
1971 new_widget =
1972 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu),
1973 GTK_TOOLBAR_CHILD_BUTTON,
1974 NULL,
1975 "",
1976 toolbar_item->tooltip, NULL,
1977 pixmap, NULL, NULL);
1978 gtk_label_set_use_underline(
1979 GTK_LABEL (((GtkToolbarChild*) (
1980 g_list_last (GTK_TOOLBAR
1981 (tool_menu_title_menu)->children)->data))->label),
1982 TRUE);
1983 gtk_container_set_border_width (GTK_CONTAINER (new_widget), 1);
1984 g_signal_connect ((gpointer) new_widget,
1985 "clicked",
1986 G_CALLBACK (insert_viewer_wrap),
1987 constructor);
1988 gtk_widget_show (new_widget);
1989
1990 lttv_toolbars_add(instance_toolbar, toolbar_item->con,
1991 toolbar_item->tooltip,
1992 toolbar_item->pixmap,
1993 new_widget);
1994
1995 }
1996
1997 }
1998
1999
2000 /* Create a main window
2001 */
2002
2003 void construct_main_window(MainWindow * parent)
2004 {
2005 g_debug("construct_main_window()");
2006 GtkWidget * new_window; /* New generated main window */
2007 MainWindow * new_m_window;/* New main window structure */
2008 GtkNotebook * notebook;
2009 LttvIAttribute *attributes =
2010 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
2011 LttvAttributeValue value;
2012
2013 new_m_window = g_new(MainWindow, 1);
2014
2015 // Add the object's information to the module's array
2016 g_main_window_list = g_slist_append(g_main_window_list, new_m_window);
2017
2018
2019 new_window = create_MWindow();
2020 gtk_widget_show (new_window);
2021
2022 new_m_window->mwindow = new_window;
2023 new_m_window->tab = NULL;
2024 new_m_window->current_tab = NULL;
2025 new_m_window->attributes = attributes;
2026
2027 g_assert(lttv_iattribute_find_by_path(attributes,
2028 "viewers/menu", LTTV_POINTER, &value));
2029 (LttvMenus*)*(value.v_pointer) = lttv_menus_new();
2030
2031 g_assert(lttv_iattribute_find_by_path(attributes_global,
2032 "viewers/toolbar", LTTV_POINTER, &value));
2033 (LttvToolbars*)*(value.v_pointer) = lttv_toolbars_new();
2034
2035 add_all_menu_toolbar_constructors(new_m_window, NULL);
2036
2037 g_object_set_data(G_OBJECT(new_window), "mainWindow", (gpointer)new_m_window);
2038 //create a default tab
2039 notebook = (GtkNotebook *)lookup_widget(new_m_window->mwindow, "MNotebook");
2040 if(notebook == NULL){
2041 g_printf("Notebook does not exist\n");
2042 return;
2043 }
2044 //for now there is no name field in LttvTraceset structure
2045 //Use "Traceset" as the label for the default tab
2046 create_tab(parent, new_m_window, notebook, "Traceset");
2047
2048 g_object_set_data_full(
2049 G_OBJECT(new_m_window->mwindow),
2050 "Main_Window_Data",
2051 new_m_window,
2052 NULL);
2053
2054 g_win_count++;
2055 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list));
2056 }
2057
2058
2059 /* Free the memory occupied by a tab structure
2060 * destroy the tab
2061 */
2062
2063 void tab_destructor(Tab * tab_instance)
2064 {
2065 int i, nb, ref_count;
2066 LttvTrace * trace;
2067
2068 if(tab_instance->attributes)
2069 g_object_unref(tab_instance->attributes);
2070
2071 if(tab_instance->mw->tab == tab_instance){
2072 tab_instance->mw->tab = tab_instance->next;
2073 }else{
2074 Tab * tmp1, *tmp = tab_instance->mw->tab;
2075 while(tmp != tab_instance){
2076 tmp1 = tmp;
2077 tmp = tmp->next;
2078 }
2079 tmp1->next = tab_instance->next;
2080 }
2081
2082 if(tab_instance->traceset_info->traceset_context != NULL){
2083 //remove state update hooks
2084 lttv_state_remove_event_hooks(
2085 (LttvTracesetState*)tab_instance->traceset_info->
2086 traceset_context);
2087 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab_instance->traceset_info->
2088 traceset_context));
2089 g_object_unref(tab_instance->traceset_info->traceset_context);
2090 }
2091 if(tab_instance->traceset_info->traceset != NULL) {
2092 nb = lttv_traceset_number(tab_instance->traceset_info->traceset);
2093 for(i = 0 ; i < nb ; i++) {
2094 trace = lttv_traceset_get(tab_instance->traceset_info->traceset, i);
2095 ref_count = lttv_trace_get_ref_number(trace);
2096 if(ref_count <= 1){
2097 ltt_trace_close(lttv_trace(trace));
2098 lttv_trace_destroy(trace);
2099 }
2100 // lttv_trace_destroy(trace);
2101 }
2102 }
2103 lttv_traceset_destroy(tab_instance->traceset_info->traceset);
2104 g_array_free(tab_instance->time_requests, TRUE);
2105 g_free(tab_instance->traceset_info);
2106 g_free(tab_instance);
2107 }
2108
2109
2110 /* Create a tab and insert it into the current main window
2111 */
2112
2113 void * create_tab(MainWindow * parent, MainWindow* current_window,
2114 GtkNotebook * notebook, char * label)
2115 {
2116 GList * list;
2117 Tab * tmp_tab;
2118 MainWindow * mw_data = current_window;
2119 LttTime tmp_time;
2120
2121 //create a new tab data structure
2122 tmp_tab = mw_data->tab;
2123 while(tmp_tab && tmp_tab->next) tmp_tab = tmp_tab->next;
2124 if(!tmp_tab){
2125 mw_data->current_tab = NULL;
2126 tmp_tab = g_new(Tab,1);
2127 mw_data->tab = tmp_tab;
2128 }else{
2129 tmp_tab->next = g_new(Tab,1);
2130 tmp_tab = tmp_tab->next;
2131 }
2132
2133 //construct and initialize the traceset_info
2134 tmp_tab->traceset_info = g_new(TracesetInfo,1);
2135 if(parent){
2136 if(parent->current_tab){
2137 tmp_tab->traceset_info->traceset =
2138 lttv_traceset_new();
2139 //FIXME lttv_traceset_copy(parent->current_tab->traceset_info->traceset);
2140 }else{
2141 tmp_tab->traceset_info->traceset = lttv_traceset_new();
2142 }
2143
2144 }else{ /* Initial window */
2145 if(mw_data->current_tab){
2146 tmp_tab->traceset_info->traceset =
2147 lttv_traceset_new();
2148 //FIXME lttv_traceset_copy(mw_data->current_tab->traceset_info->traceset);
2149 }else{
2150 tmp_tab->traceset_info->traceset = lttv_traceset_new();
2151 /* Add the command line trace */
2152 if(g_init_trace != NULL){
2153 lttv_traceset_add(tmp_tab->traceset_info->traceset, g_init_trace);
2154 }
2155 }
2156 }
2157
2158 //FIXME copy not implemented in lower level
2159 tmp_tab->traceset_info->traceset_context =
2160 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
2161 g_assert(tmp_tab->traceset_info->traceset_context != NULL);
2162 lttv_context_init(
2163 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context),
2164 tmp_tab->traceset_info->traceset);
2165 //add state update hooks
2166 lttv_state_add_event_hooks(
2167 (LttvTracesetState*)tmp_tab->traceset_info->traceset_context);
2168
2169 //determine the current_time and time_window of the tab
2170 if(mw_data->current_tab){
2171 // Will have to read directly at the main window level, as we want
2172 // to be able to modify a traceset on the fly.
2173 tmp_tab->time_window = mw_data->current_tab->time_window;
2174 tmp_tab->current_time = mw_data->current_tab->current_time;
2175 }else{
2176 // Will have to read directly at the main window level, as we want
2177 // to be able to modify a traceset on the fly.
2178 // get_traceset_time_span(mw_data,&tmp_tab->traceStartTime, &tmp_tab->traceEndTime);
2179 tmp_tab->time_window.start_time =
2180 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->startTime;
2181 if(DEFAULT_TIME_WIDTH_S <
2182 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->endTime.tv_sec)
2183 tmp_time.tv_sec = DEFAULT_TIME_WIDTH_S;
2184 else
2185 tmp_time.tv_sec =
2186 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->endTime.tv_sec;
2187 tmp_time.tv_nsec = 0;
2188 tmp_tab->time_window.time_width = tmp_time ;
2189 tmp_tab->current_time.tv_sec =
2190 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->startTime.tv_sec;
2191 tmp_tab->current_time.tv_nsec =
2192 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->startTime.tv_nsec;
2193 }
2194 /* Become the current tab */
2195 mw_data->current_tab = tmp_tab;
2196
2197 tmp_tab->attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
2198 tmp_tab->multi_vpaned = (GtkMultiVPaned*)gtk_multi_vpaned_new();
2199 tmp_tab->multi_vpaned->mw = mw_data;
2200 gtk_widget_show((GtkWidget*)tmp_tab->multi_vpaned);
2201 tmp_tab->next = NULL;
2202 tmp_tab->mw = mw_data;
2203
2204 tmp_tab->label = gtk_label_new (label);
2205 gtk_widget_show (tmp_tab->label);
2206
2207 tmp_tab->time_requests = g_array_new(FALSE, FALSE, sizeof(TimeRequest));
2208 tmp_tab->time_request_pending = FALSE;
2209
2210 g_object_set_data_full(
2211 G_OBJECT(tmp_tab->multi_vpaned),
2212 "Tab_Info",
2213 tmp_tab,
2214 (GDestroyNotify)tab_destructor);
2215
2216 //insert tab into notebook
2217 gtk_notebook_append_page(notebook, (GtkWidget*)tmp_tab->multi_vpaned, tmp_tab->label);
2218 list = gtk_container_get_children(GTK_CONTAINER(notebook));
2219 gtk_notebook_set_current_page(notebook,g_list_length(list)-1);
2220 // always show : not if(g_list_length(list)>1)
2221 gtk_notebook_set_show_tabs(notebook, TRUE);
2222
2223 }
2224
2225 /**
2226 * Function to show each viewer in the current tab.
2227 * It will be called by main window, call show on each registered viewer,
2228 * will call process traceset and then it will
2229 * @param main_win the main window the viewer belongs to.
2230 */
2231 //FIXME Only one time request maximum for now!
2232 void show_viewer(MainWindow *main_win)
2233 {
2234 LttvAttributeValue value;
2235 LttvHooks * tmp;
2236 int i;
2237 LttvTracesetContext * tsc =
2238 (LttvTracesetContext*)main_win->current_tab->
2239 traceset_info->traceset_context;
2240
2241 g_assert(lttv_iattribute_find_by_path(main_win->current_tab->attributes,
2242 "hooks/showviewer", LTTV_POINTER, &value));
2243 tmp = (LttvHooks*)*(value.v_pointer);
2244 if(tmp == NULL)
2245 {
2246 g_warning("The viewer(s) did not add any show hook");
2247 return;
2248 }
2249
2250
2251 // Call the show, where viewers add hooks to context and fill the
2252 // time and number of events requested it the time_requests GArray.
2253 lttv_hooks_call(tmp, NULL);
2254
2255
2256 }
2257
2258
2259 gboolean execute_time_requests(MainWindow * mw)
2260 {
2261 call_pending_read_hooks(mw);
2262
2263 return FALSE; // automatically removed from the list of event sources
2264 }
2265
This page took 0.078576 seconds and 4 git commands to generate.