Viewer contstructor change
[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
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
46extern LttvTrace *g_init_trace ;
47
48
49/** Array containing instanced objects. */
50extern GSList * g_main_window_list;
51
52static int g_win_count = 0;
53
54/** MD : keep old directory. */
55static char remember_plugins_dir[PATH_LENGTH] = "";
56static char remember_trace_dir[PATH_LENGTH] = "";
57
58
59MainWindow * get_window_data_struct(GtkWidget * widget);
60char * get_unload_module(char ** loaded_module_name, int nb_module);
61char * get_remove_trace(char ** all_trace_name, int nb_trace);
62char * get_selection(char ** all_name, int nb, char *title, char * column_title);
63gboolean get_filter_selection(LttvTracesetSelector *s, char *title, char * column_title);
64void * create_tab(MainWindow * parent, MainWindow * current_window,
65 GtkNotebook * notebook, char * label);
66
67void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor);
68void update_filter(LttvTracesetSelector *s, GtkTreeStore *store );
69
70void checkbox_changed(GtkTreeView *treeview,
71 GtkTreePath *arg1,
72 GtkTreeViewColumn *arg2,
73 gpointer user_data);
74void remove_trace_from_traceset_selector(GtkMultiVPaned * paned, unsigned i);
75void add_trace_into_traceset_selector(GtkMultiVPaned * paned, LttTrace * trace);
76
77LttvTracesetSelector * construct_traceset_selector(LttvTraceset * traceset);
78
79void call_pending_read_hooks(MainWindow * mw_data);
80unsigned get_max_event_number(MainWindow * mw_data);
81
82enum {
83 CHECKBOX_COLUMN,
84 NAME_COLUMN,
85 TOTAL_COLUMNS
86};
87
88enum
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
98LttvTracesetSelector * 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
154void
155insert_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 */
165void 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
201void 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
208gboolean 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
250MainWindow * 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
273void 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
291void 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
298void 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
309void 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
322void 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
357unsigned 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
386gint 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
391void 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
505void 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
561void 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
672void 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
700void 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
823void save(GtkWidget * widget, gpointer user_data)
824{
825 g_printf("Save\n");
826}
827
828void 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
839void 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
915void zoom_in(GtkWidget * widget, gpointer user_data)
916{
917 zoom(widget, 2);
918}
919
920void zoom_out(GtkWidget * widget, gpointer user_data)
921{
922 zoom(widget, 0.5);
923}
924
925void zoom_extended(GtkWidget * widget, gpointer user_data)
926{
927 zoom(widget, 0);
928}
929
930void go_to_time(GtkWidget * widget, gpointer user_data)
931{
932 g_printf("Go to time\n");
933}
934
935void show_time_frame(GtkWidget * widget, gpointer user_data)
936{
937 g_printf("Show time frame\n");
938}
939
940
941/* callback function */
942
943void
944on_empty_traceset_activate (GtkMenuItem *menuitem,
945 gpointer user_data)
946{
947 create_new_window((GtkWidget*)menuitem, user_data, FALSE);
948}
949
950
951void
952on_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
962void 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
976void
977on_tab_activate (GtkMenuItem *menuitem,
978 gpointer user_data)
979{
980 create_new_tab((GtkWidget*)menuitem, user_data);
981}
982
983
984void
985on_open_activate (GtkMenuItem *menuitem,
986 gpointer user_data)
987{
988 open_traceset((GtkWidget*)menuitem, user_data);
989}
990
991
992void
993on_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
1004void
1005on_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
1039void
1040on_add_trace_activate (GtkMenuItem *menuitem,
1041 gpointer user_data)
1042{
1043 add_trace((GtkWidget*)menuitem, user_data);
1044}
1045
1046
1047void
1048on_remove_trace_activate (GtkMenuItem *menuitem,
1049 gpointer user_data)
1050{
1051 remove_trace((GtkWidget*)menuitem, user_data);
1052}
1053
1054
1055void
1056on_save_activate (GtkMenuItem *menuitem,
1057 gpointer user_data)
1058{
1059 save((GtkWidget*)menuitem, user_data);
1060}
1061
1062
1063void
1064on_save_as_activate (GtkMenuItem *menuitem,
1065 gpointer user_data)
1066{
1067 save_as((GtkWidget*)menuitem, user_data);
1068}
1069
1070
1071void
1072on_quit_activate (GtkMenuItem *menuitem,
1073 gpointer user_data)
1074{
1075 gtk_main_quit ();
1076}
1077
1078
1079void
1080on_cut_activate (GtkMenuItem *menuitem,
1081 gpointer user_data)
1082{
1083 g_printf("Cut\n");
1084}
1085
1086
1087void
1088on_copy_activate (GtkMenuItem *menuitem,
1089 gpointer user_data)
1090{
1091 g_printf("Copye\n");
1092}
1093
1094
1095void
1096on_paste_activate (GtkMenuItem *menuitem,
1097 gpointer user_data)
1098{
1099 g_printf("Paste\n");
1100}
1101
1102
1103void
1104on_delete_activate (GtkMenuItem *menuitem,
1105 gpointer user_data)
1106{
1107 g_printf("Delete\n");
1108}
1109
1110
1111void
1112on_zoom_in_activate (GtkMenuItem *menuitem,
1113 gpointer user_data)
1114{
1115 zoom_in((GtkWidget*)menuitem, user_data);
1116}
1117
1118
1119void
1120on_zoom_out_activate (GtkMenuItem *menuitem,
1121 gpointer user_data)
1122{
1123 zoom_out((GtkWidget*)menuitem, user_data);
1124}
1125
1126
1127void
1128on_zoom_extended_activate (GtkMenuItem *menuitem,
1129 gpointer user_data)
1130{
1131 zoom_extended((GtkWidget*)menuitem, user_data);
1132}
1133
1134
1135void
1136on_go_to_time_activate (GtkMenuItem *menuitem,
1137 gpointer user_data)
1138{
1139 go_to_time((GtkWidget*)menuitem, user_data);
1140}
1141
1142
1143void
1144on_show_time_frame_activate (GtkMenuItem *menuitem,
1145 gpointer user_data)
1146{
1147 show_time_frame((GtkWidget*)menuitem, user_data);
1148}
1149
1150
1151void
1152on_move_viewer_up_activate (GtkMenuItem *menuitem,
1153 gpointer user_data)
1154{
1155 move_up_viewer((GtkWidget*)menuitem, user_data);
1156}
1157
1158
1159void
1160on_move_viewer_down_activate (GtkMenuItem *menuitem,
1161 gpointer user_data)
1162{
1163 move_down_viewer((GtkWidget*)menuitem, user_data);
1164}
1165
1166
1167void
1168on_remove_viewer_activate (GtkMenuItem *menuitem,
1169 gpointer user_data)
1170{
1171 delete_viewer((GtkWidget*)menuitem, user_data);
1172}
1173
1174void
1175on_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
1195void
1196on_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
1208void
1209on_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_slist_foreach(g_main_window_list, (gpointer)insert_menu_toolbar_item,
1237 NULL);
1238 g_strfreev(dir);
1239 case GTK_RESPONSE_REJECT:
1240 case GTK_RESPONSE_CANCEL:
1241 default:
1242 gtk_widget_destroy((GtkWidget*)file_selector);
1243 break;
1244 }
1245 g_printf("Load module: %s\n", str);
1246}
1247
1248
1249/* Display all loaded modules, let user to select a module to unload
1250 * by calling lttv_module_unload
1251 */
1252
1253void
1254on_unload_module_activate (GtkMenuItem *menuitem,
1255 gpointer user_data)
1256{
1257 int i;
1258 GPtrArray *name;
1259 char *unload_module_name;
1260 guint nb;
1261 LttvLibrary *library;
1262 LttvLibraryInfo library_info;
1263 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
1264
1265 name = g_ptr_array_new();
1266 nb = lttv_library_number();
1267
1268 for(i=0;i<nb;i++){
1269 library = lttv_library_get(i);
1270 lttv_library_info(library, &library_info);
1271 if(library_info.load_count > 0) g_ptr_array_add(name, library_info.name);
1272 }
1273
1274 unload_module_name =get_unload_module((char **)(name->pdata), name->len);
1275
1276 if(unload_module_name){
1277 for(i=0;i<nb;i++){
1278 library = lttv_library_get(i);
1279 lttv_library_info(library, &library_info);
1280 if(strcmp(unload_module_name, library_info.name) == 0){
1281 lttv_library_unload(library);
1282 break;
1283 }
1284 }
1285 }
1286
1287 g_ptr_array_free(name, TRUE);
1288}
1289
1290
1291/* Display a directory dialogue to let user select a path for module searching
1292 */
1293
1294void
1295on_add_module_search_path_activate (GtkMenuItem *menuitem,
1296 gpointer user_data)
1297{
1298 GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select module path");
1299 const char * dir;
1300 gint id;
1301
1302 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
1303 if(remember_plugins_dir[0] != '\0')
1304 gtk_dir_selection_set_filename(file_selector, remember_plugins_dir);
1305
1306 id = gtk_dialog_run(GTK_DIALOG(file_selector));
1307 switch(id){
1308 case GTK_RESPONSE_ACCEPT:
1309 case GTK_RESPONSE_OK:
1310 dir = gtk_dir_selection_get_dir (file_selector);
1311 strncpy(remember_plugins_dir,dir,PATH_LENGTH);
1312 strncat(remember_plugins_dir,"/",PATH_LENGTH);
1313 lttv_library_path_add(dir);
1314 case GTK_RESPONSE_REJECT:
1315 case GTK_RESPONSE_CANCEL:
1316 default:
1317 gtk_widget_destroy((GtkWidget*)file_selector);
1318 break;
1319 }
1320}
1321
1322
1323void
1324on_color_activate (GtkMenuItem *menuitem,
1325 gpointer user_data)
1326{
1327 g_printf("Color\n");
1328}
1329
1330
1331void
1332on_filter_activate (GtkMenuItem *menuitem,
1333 gpointer user_data)
1334{
1335 g_printf("Filter\n");
1336}
1337
1338
1339void
1340on_save_configuration_activate (GtkMenuItem *menuitem,
1341 gpointer user_data)
1342{
1343 g_printf("Save configuration\n");
1344}
1345
1346
1347void
1348on_content_activate (GtkMenuItem *menuitem,
1349 gpointer user_data)
1350{
1351 g_printf("Content\n");
1352}
1353
1354
1355void
1356on_about_activate (GtkMenuItem *menuitem,
1357 gpointer user_data)
1358{
1359 g_printf("About...\n");
1360}
1361
1362
1363void
1364on_button_new_clicked (GtkButton *button,
1365 gpointer user_data)
1366{
1367 create_new_window((GtkWidget*)button, user_data, TRUE);
1368}
1369
1370void
1371on_button_new_tab_clicked (GtkButton *button,
1372 gpointer user_data)
1373{
1374 create_new_tab((GtkWidget*)button, user_data);
1375}
1376
1377void
1378on_button_open_clicked (GtkButton *button,
1379 gpointer user_data)
1380{
1381 open_traceset((GtkWidget*)button, user_data);
1382}
1383
1384
1385void
1386on_button_add_trace_clicked (GtkButton *button,
1387 gpointer user_data)
1388{
1389 add_trace((GtkWidget*)button, user_data);
1390}
1391
1392
1393void
1394on_button_remove_trace_clicked (GtkButton *button,
1395 gpointer user_data)
1396{
1397 remove_trace((GtkWidget*)button, user_data);
1398}
1399
1400
1401void
1402on_button_save_clicked (GtkButton *button,
1403 gpointer user_data)
1404{
1405 save((GtkWidget*)button, user_data);
1406}
1407
1408
1409void
1410on_button_save_as_clicked (GtkButton *button,
1411 gpointer user_data)
1412{
1413 save_as((GtkWidget*)button, user_data);
1414}
1415
1416
1417void
1418on_button_zoom_in_clicked (GtkButton *button,
1419 gpointer user_data)
1420{
1421 zoom_in((GtkWidget*)button, user_data);
1422}
1423
1424
1425void
1426on_button_zoom_out_clicked (GtkButton *button,
1427 gpointer user_data)
1428{
1429 zoom_out((GtkWidget*)button, user_data);
1430}
1431
1432
1433void
1434on_button_zoom_extended_clicked (GtkButton *button,
1435 gpointer user_data)
1436{
1437 zoom_extended((GtkWidget*)button, user_data);
1438}
1439
1440
1441void
1442on_button_go_to_time_clicked (GtkButton *button,
1443 gpointer user_data)
1444{
1445 go_to_time((GtkWidget*)button, user_data);
1446}
1447
1448
1449void
1450on_button_show_time_frame_clicked (GtkButton *button,
1451 gpointer user_data)
1452{
1453 show_time_frame((GtkWidget*)button, user_data);
1454}
1455
1456
1457void
1458on_button_move_up_clicked (GtkButton *button,
1459 gpointer user_data)
1460{
1461 move_up_viewer((GtkWidget*)button, user_data);
1462}
1463
1464
1465void
1466on_button_move_down_clicked (GtkButton *button,
1467 gpointer user_data)
1468{
1469 move_down_viewer((GtkWidget*)button, user_data);
1470}
1471
1472
1473void
1474on_button_delete_viewer_clicked (GtkButton *button,
1475 gpointer user_data)
1476{
1477 delete_viewer((GtkWidget*)button, user_data);
1478}
1479
1480void
1481on_MWindow_destroy (GtkObject *object,
1482 gpointer user_data)
1483{
1484 MainWindow *Main_Window = get_window_data_struct((GtkWidget*)object);
1485 GtkWidget *widget;
1486 Tab *tab = Main_Window->tab;
1487
1488 g_printf("There are : %d windows\n",g_slist_length(g_main_window_list));
1489
1490 g_win_count--;
1491 if(g_win_count == 0)
1492 gtk_main_quit ();
1493}
1494
1495gboolean
1496on_MWindow_configure (GtkWidget *widget,
1497 GdkEventConfigure *event,
1498 gpointer user_data)
1499{
1500 MainWindow * mw_data = get_window_data_struct((GtkWidget*)widget);
1501 float width = event->width;
1502 Tab * tab = mw_data->tab;
1503 TimeWindow time_win;
1504 double ratio;
1505 TimeInterval *time_span;
1506 LttTime time;
1507
1508 // MD : removed time width modification upon resizing of the main window.
1509 // The viewers will redraw themselves completely, without time interval
1510 // modification.
1511/* while(tab){
1512 if(mw_data->window_width){
1513 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
1514 time_win = tab->time_window;
1515 ratio = width / mw_data->window_width;
1516 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
1517 time = ltt_time_sub(time_span->endTime, time_win.start_time);
1518 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
1519 tab->time_window.time_width = time;
1520 }
1521 }
1522 tab = tab->next;
1523 }
1524
1525 mw_data->window_width = (int)width;
1526 */
1527 return FALSE;
1528}
1529
1530/* Set current tab
1531 */
1532
1533void
1534on_MNotebook_switch_page (GtkNotebook *notebook,
1535 GtkNotebookPage *page,
1536 guint page_num,
1537 gpointer user_data)
1538{
1539 MainWindow * mw = get_window_data_struct((GtkWidget*)notebook);
1540 Tab * tab = mw->tab;
1541
1542 while(page_num){
1543 tab = tab->next;
1544 page_num--;
1545 }
1546 mw->current_tab = tab;
1547}
1548
1549
1550/* callback function to check or uncheck the check box (filter)
1551 */
1552
1553void checkbox_changed(GtkTreeView *treeview,
1554 GtkTreePath *arg1,
1555 GtkTreeViewColumn *arg2,
1556 gpointer user_data)
1557{
1558 GtkTreeStore * store = (GtkTreeStore *)gtk_tree_view_get_model (treeview);
1559 GtkTreeIter iter;
1560 gboolean value;
1561
1562 if (gtk_tree_model_get_iter ((GtkTreeModel *)store, &iter, arg1)){
1563 gtk_tree_model_get ((GtkTreeModel *)store, &iter, CHECKBOX_COLUMN, &value, -1);
1564 value = value? FALSE : TRUE;
1565 gtk_tree_store_set (GTK_TREE_STORE (store), &iter, CHECKBOX_COLUMN, value, -1);
1566 }
1567
1568}
1569
1570
1571/* According to user's selection, update selector(filter)
1572 */
1573
1574void update_filter(LttvTracesetSelector *s, GtkTreeStore *store )
1575{
1576 GtkTreeIter iter, child_iter, child_iter1, child_iter2;
1577 int i, j, k, nb_eventtype;
1578 LttvTraceSelector * trace;
1579 LttvTracefileSelector * tracefile;
1580 LttvEventtypeSelector * eventtype;
1581 gboolean value, value1, value2;
1582
1583 if(gtk_tree_model_get_iter_first((GtkTreeModel*)store, &iter)){
1584 i = 0;
1585 do{
1586 trace = lttv_traceset_selector_trace_get(s, i);
1587 nb_eventtype = lttv_trace_selector_eventtype_number(trace);
1588 gtk_tree_model_get ((GtkTreeModel*)store, &iter, CHECKBOX_COLUMN, &value,-1);
1589 if(value){
1590 j = 0;
1591 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter, &iter)){
1592 do{
1593 if(j<1){//eventtype selector for trace
1594 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter, CHECKBOX_COLUMN, &value2,-1);
1595 if(value2){
1596 k=0;
1597 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter1, &child_iter)){
1598 do{
1599 eventtype = lttv_trace_selector_eventtype_get(trace,k);
1600 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter1, CHECKBOX_COLUMN, &value2,-1);
1601 lttv_eventtype_selector_set_selected(eventtype,value2);
1602 k++;
1603 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter1));
1604 }
1605 }
1606 }else{ //tracefile selector
1607 tracefile = lttv_trace_selector_tracefile_get(trace, j - 1);
1608 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter, CHECKBOX_COLUMN, &value1,-1);
1609 lttv_tracefile_selector_set_selected(tracefile,value1);
1610 if(value1){
1611 gtk_tree_model_iter_children((GtkTreeModel*)store, &child_iter1, &child_iter); //eventtype selector
1612 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter1, CHECKBOX_COLUMN, &value2,-1);
1613 if(value2){
1614 k = 0;
1615 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter2, &child_iter1)){
1616 do{//eventtype selector for tracefile
1617 eventtype = lttv_tracefile_selector_eventtype_get(tracefile,k);
1618 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter2, CHECKBOX_COLUMN, &value2,-1);
1619 lttv_eventtype_selector_set_selected(eventtype,value2);
1620 k++;
1621 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter2));
1622 }
1623 }
1624 }
1625 }
1626 j++;
1627 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter));
1628 }
1629 }
1630 lttv_trace_selector_set_selected(trace,value);
1631 i++;
1632 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &iter));
1633 }
1634}
1635
1636
1637/* Display a dialogue showing all eventtypes and traces, let user to select the interested
1638 * eventtypes, tracefiles and traces (filter)
1639 */
1640
1641gboolean get_filter_selection(LttvTracesetSelector *s,char *title, char * column_title)
1642{
1643 GtkWidget * dialogue;
1644 GtkTreeStore * store;
1645 GtkWidget * tree;
1646 GtkWidget * scroll_win;
1647 GtkCellRenderer * renderer;
1648 GtkTreeViewColumn * column;
1649 GtkTreeIter iter, child_iter, child_iter1, child_iter2;
1650 int i, j, k, id, nb_trace, nb_tracefile, nb_eventtype;
1651 LttvTraceSelector * trace;
1652 LttvTracefileSelector * tracefile;
1653 LttvEventtypeSelector * eventtype;
1654 char * name;
1655 gboolean checked;
1656
1657 dialogue = gtk_dialog_new_with_buttons(title,
1658 NULL,
1659 GTK_DIALOG_MODAL,
1660 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
1661 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
1662 NULL);
1663 gtk_window_set_default_size((GtkWindow*)dialogue, 300, 500);
1664
1665 store = gtk_tree_store_new (TOTAL_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING);
1666 tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
1667 g_object_unref (G_OBJECT (store));
1668 g_signal_connect (G_OBJECT (tree), "row-activated",
1669 G_CALLBACK (checkbox_changed),
1670 NULL);
1671
1672
1673 renderer = gtk_cell_renderer_toggle_new ();
1674 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle *)renderer, FALSE);
1675
1676 g_object_set (G_OBJECT (renderer),"activatable", TRUE, NULL);
1677
1678 column = gtk_tree_view_column_new_with_attributes ("Checkbox",
1679 renderer,
1680 "active", CHECKBOX_COLUMN,
1681 NULL);
1682 gtk_tree_view_column_set_alignment (column, 0.5);
1683 gtk_tree_view_column_set_fixed_width (column, 20);
1684 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
1685
1686 renderer = gtk_cell_renderer_text_new ();
1687 column = gtk_tree_view_column_new_with_attributes (column_title,
1688 renderer,
1689 "text", NAME_COLUMN,
1690 NULL);
1691 gtk_tree_view_column_set_alignment (column, 0.0);
1692 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
1693 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree), FALSE);
1694
1695 scroll_win = gtk_scrolled_window_new (NULL, NULL);
1696 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
1697 GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
1698 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
1699
1700 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
1701
1702 gtk_widget_show(scroll_win);
1703 gtk_widget_show(tree);
1704
1705 nb_trace = lttv_traceset_selector_trace_number(s);
1706 for(i=0;i<nb_trace;i++){
1707 trace = lttv_traceset_selector_trace_get(s, i);
1708 name = lttv_trace_selector_get_name(trace);
1709 gtk_tree_store_append (store, &iter, NULL);
1710 checked = lttv_trace_selector_get_selected(trace);
1711 gtk_tree_store_set (store, &iter,
1712 CHECKBOX_COLUMN,checked,
1713 NAME_COLUMN,name,
1714 -1);
1715
1716 gtk_tree_store_append (store, &child_iter, &iter);
1717 gtk_tree_store_set (store, &child_iter,
1718 CHECKBOX_COLUMN, checked,
1719 NAME_COLUMN,"eventtype",
1720 -1);
1721
1722 nb_eventtype = lttv_trace_selector_eventtype_number(trace);
1723 for(j=0;j<nb_eventtype;j++){
1724 eventtype = lttv_trace_selector_eventtype_get(trace,j);
1725 name = lttv_eventtype_selector_get_name(eventtype);
1726 checked = lttv_eventtype_selector_get_selected(eventtype);
1727 gtk_tree_store_append (store, &child_iter1, &child_iter);
1728 gtk_tree_store_set (store, &child_iter1,
1729 CHECKBOX_COLUMN, checked,
1730 NAME_COLUMN,name,
1731 -1);
1732 }
1733
1734 nb_tracefile = lttv_trace_selector_tracefile_number(trace);
1735 for(j=0;j<nb_tracefile;j++){
1736 tracefile = lttv_trace_selector_tracefile_get(trace, j);
1737 name = lttv_tracefile_selector_get_name(tracefile);
1738 gtk_tree_store_append (store, &child_iter, &iter);
1739 checked = lttv_tracefile_selector_get_selected(tracefile);
1740 gtk_tree_store_set (store, &child_iter,
1741 CHECKBOX_COLUMN, checked,
1742 NAME_COLUMN,name,
1743 -1);
1744
1745 gtk_tree_store_append (store, &child_iter1, &child_iter);
1746 gtk_tree_store_set (store, &child_iter1,
1747 CHECKBOX_COLUMN, checked,
1748 NAME_COLUMN,"eventtype",
1749 -1);
1750
1751 for(k=0;k<nb_eventtype;k++){
1752 eventtype = lttv_tracefile_selector_eventtype_get(tracefile,k);
1753 name = lttv_eventtype_selector_get_name(eventtype);
1754 checked = lttv_eventtype_selector_get_selected(eventtype);
1755 gtk_tree_store_append (store, &child_iter2, &child_iter1);
1756 gtk_tree_store_set (store, &child_iter2,
1757 CHECKBOX_COLUMN, checked,
1758 NAME_COLUMN,name,
1759 -1);
1760 }
1761 }
1762 }
1763
1764 id = gtk_dialog_run(GTK_DIALOG(dialogue));
1765 switch(id){
1766 case GTK_RESPONSE_ACCEPT:
1767 case GTK_RESPONSE_OK:
1768 update_filter(s, store);
1769 gtk_widget_destroy(dialogue);
1770 return TRUE;
1771 case GTK_RESPONSE_REJECT:
1772 case GTK_RESPONSE_CANCEL:
1773 default:
1774 gtk_widget_destroy(dialogue);
1775 break;
1776 }
1777 return FALSE;
1778}
1779
1780
1781/* Select a trace which will be removed from traceset
1782 */
1783
1784char * get_remove_trace(char ** all_trace_name, int nb_trace)
1785{
1786 return get_selection(all_trace_name, nb_trace,
1787 "Select a trace", "Trace pathname");
1788}
1789
1790
1791/* Select a module which will be unloaded
1792 */
1793
1794char * get_unload_module(char ** loaded_module_name, int nb_module)
1795{
1796 return get_selection(loaded_module_name, nb_module,
1797 "Select an unload module", "Module pathname");
1798}
1799
1800
1801/* Display a dialogue which shows all selectable items, let user to
1802 * select one of them
1803 */
1804
1805char * get_selection(char ** loaded_module_name, int nb_module,
1806 char *title, char * column_title)
1807{
1808 GtkWidget * dialogue;
1809 GtkWidget * scroll_win;
1810 GtkWidget * tree;
1811 GtkListStore * store;
1812 GtkTreeViewColumn * column;
1813 GtkCellRenderer * renderer;
1814 GtkTreeSelection * select;
1815 GtkTreeIter iter;
1816 gint id, i;
1817 char * unload_module_name = NULL;
1818
1819 dialogue = gtk_dialog_new_with_buttons(title,
1820 NULL,
1821 GTK_DIALOG_MODAL,
1822 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
1823 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
1824 NULL);
1825 gtk_window_set_default_size((GtkWindow*)dialogue, 500, 200);
1826
1827 scroll_win = gtk_scrolled_window_new (NULL, NULL);
1828 gtk_widget_show ( scroll_win);
1829 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
1830 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1831
1832 store = gtk_list_store_new (N_COLUMNS,G_TYPE_STRING);
1833 tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL (store));
1834 gtk_widget_show ( tree);
1835 g_object_unref (G_OBJECT (store));
1836
1837 renderer = gtk_cell_renderer_text_new ();
1838 column = gtk_tree_view_column_new_with_attributes (column_title,
1839 renderer,
1840 "text", MODULE_COLUMN,
1841 NULL);
1842 gtk_tree_view_column_set_alignment (column, 0.5);
1843 gtk_tree_view_column_set_fixed_width (column, 150);
1844 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
1845
1846 select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
1847 gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
1848
1849 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
1850
1851 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
1852
1853 for(i=0;i<nb_module;i++){
1854 gtk_list_store_append (store, &iter);
1855 gtk_list_store_set (store, &iter, MODULE_COLUMN,loaded_module_name[i],-1);
1856 }
1857
1858 id = gtk_dialog_run(GTK_DIALOG(dialogue));
1859 switch(id){
1860 case GTK_RESPONSE_ACCEPT:
1861 case GTK_RESPONSE_OK:
1862 if (gtk_tree_selection_get_selected (select, (GtkTreeModel**)&store, &iter)){
1863 gtk_tree_model_get ((GtkTreeModel*)store, &iter, MODULE_COLUMN, &unload_module_name, -1);
1864 }
1865 case GTK_RESPONSE_REJECT:
1866 case GTK_RESPONSE_CANCEL:
1867 default:
1868 gtk_widget_destroy(dialogue);
1869 break;
1870 }
1871
1872 return unload_module_name;
1873}
1874
1875
1876/* hash funtions
1877 */
1878
1879void main_window_destroy_hash_key(gpointer key)
1880{
1881 g_free(key);
1882}
1883
1884void main_window_destroy_hash_data(gpointer data)
1885{
1886}
1887
1888
1889/* Insert menu entry and tool button into all main windows for modules
1890 * It checks whether the menu entry or tool button exists or not,
1891 * if they do not exist, then construct the widget and insert them
1892 * into all main windows
1893 */
1894
1895void insert_menu_toolbar_item(MainWindow * mw, gpointer user_data)
1896{
1897 int i;
1898 GdkPixbuf *pixbuf;
1899 lttvwindow_viewer_constructor constructor;
1900 LttvMenus * menu;
1901 LttvToolbars * toolbar;
1902 lttv_menu_closure *menu_item;
1903 lttv_toolbar_closure *toolbar_item;
1904 LttvAttributeValue value;
1905 LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
1906 GtkWidget * tool_menu_title_menu, *insert_view, *pixmap, *tmp;
1907
1908 g_assert(lttv_iattribute_find_by_path(attributes,
1909 "viewers/menu", LTTV_POINTER, &value));
1910 menu = (LttvMenus*)*(value.v_pointer);
1911
1912 if(menu){
1913 for(i=0;i<menu->len;i++){
1914 menu_item = &g_array_index(menu, lttv_menu_closure, i);
1915 tmp = g_hash_table_lookup(mw->hash_menu_item, g_strdup(menu_item->menuText));
1916 if(tmp)continue;
1917 constructor = menu_item->con;
1918 tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
1919 insert_view = gtk_menu_item_new_with_mnemonic (menu_item->menuText);
1920 gtk_widget_show (insert_view);
1921 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu), insert_view);
1922 g_signal_connect ((gpointer) insert_view, "activate",
1923 G_CALLBACK (insert_viewer_wrap),
1924 constructor);
1925 g_hash_table_insert(mw->hash_menu_item, g_strdup(menu_item->menuText),
1926 insert_view);
1927 }
1928 }
1929
1930 g_assert(lttv_iattribute_find_by_path(attributes,
1931 "viewers/toolbar", LTTV_POINTER, &value));
1932 toolbar = (LttvToolbars*)*(value.v_pointer);
1933
1934 if(toolbar){
1935 for(i=0;i<toolbar->len;i++){
1936 toolbar_item = &g_array_index(toolbar, lttv_toolbar_closure, i);
1937 tmp = g_hash_table_lookup(mw->hash_toolbar_item, g_strdup(toolbar_item->tooltip));
1938 if(tmp)continue;
1939 constructor = toolbar_item->con;
1940 tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1");
1941 pixbuf = gdk_pixbuf_new_from_xpm_data ((const char**)toolbar_item->pixmap);
1942 pixmap = gtk_image_new_from_pixbuf(pixbuf);
1943 insert_view = gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu),
1944 GTK_TOOLBAR_CHILD_BUTTON,
1945 NULL,
1946 "",
1947 toolbar_item->tooltip, NULL,
1948 pixmap, NULL, NULL);
1949 gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (tool_menu_title_menu)->children)->data))->label), TRUE);
1950 gtk_widget_show (insert_view);
1951 gtk_container_set_border_width (GTK_CONTAINER (insert_view), 1);
1952 g_signal_connect ((gpointer) insert_view, "clicked",G_CALLBACK (insert_viewer_wrap),constructor);
1953 g_hash_table_insert(mw->hash_toolbar_item, g_strdup(toolbar_item->tooltip),
1954 insert_view);
1955 }
1956 }
1957}
1958
1959
1960/* Create a main window
1961 */
1962
1963void construct_main_window(MainWindow * parent)
1964{
1965 g_debug("construct_main_window()");
1966 GtkWidget * new_window; /* New generated main window */
1967 MainWindow * new_m_window;/* New main window structure */
1968 GtkNotebook * notebook;
1969 LttvIAttribute *attributes =
1970 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
1971 LttvAttributeValue value;
1972
1973 new_m_window = g_new(MainWindow, 1);
1974
1975 // Add the object's information to the module's array
1976 g_main_window_list = g_slist_append(g_main_window_list, new_m_window);
1977
1978
1979 new_window = create_MWindow();
1980 gtk_widget_show (new_window);
1981
1982 new_m_window->mwindow = new_window;
1983 new_m_window->tab = NULL;
1984 new_m_window->current_tab = NULL;
1985 new_m_window->attributes = attributes;
1986
1987 new_m_window->hash_menu_item = g_hash_table_new_full (g_str_hash, g_str_equal,
1988 main_window_destroy_hash_key,
1989 main_window_destroy_hash_data);
1990 new_m_window->hash_toolbar_item = g_hash_table_new_full (g_str_hash, g_str_equal,
1991 main_window_destroy_hash_key,
1992 main_window_destroy_hash_data);
1993
1994 insert_menu_toolbar_item(new_m_window, NULL);
1995
1996 g_object_set_data(G_OBJECT(new_window), "mainWindow", (gpointer)new_m_window);
1997 //create a default tab
1998 notebook = (GtkNotebook *)lookup_widget(new_m_window->mwindow, "MNotebook");
1999 if(notebook == NULL){
2000 g_printf("Notebook does not exist\n");
2001 return;
2002 }
2003 //for now there is no name field in LttvTraceset structure
2004 //Use "Traceset" as the label for the default tab
2005 create_tab(parent, new_m_window, notebook, "Traceset");
2006
2007 g_object_set_data_full(
2008 G_OBJECT(new_m_window->mwindow),
2009 "Main_Window_Data",
2010 new_m_window,
2011 (GDestroyNotify)main_window_free);
2012
2013 g_win_count++;
2014}
2015
2016
2017/* Free the memory occupied by a tab structure
2018 * destroy the tab
2019 */
2020
2021void tab_destructor(Tab * tab_instance)
2022{
2023 int i, nb, ref_count;
2024 LttvTrace * trace;
2025
2026 if(tab_instance->attributes)
2027 g_object_unref(tab_instance->attributes);
2028
2029 if(tab_instance->mw->tab == tab_instance){
2030 tab_instance->mw->tab = tab_instance->next;
2031 }else{
2032 Tab * tmp1, *tmp = tab_instance->mw->tab;
2033 while(tmp != tab_instance){
2034 tmp1 = tmp;
2035 tmp = tmp->next;
2036 }
2037 tmp1->next = tab_instance->next;
2038 }
2039
2040 if(tab_instance->traceset_info->traceset_context != NULL){
2041 //remove state update hooks
2042 lttv_state_remove_event_hooks(
2043 (LttvTracesetState*)tab_instance->traceset_info->
2044 traceset_context);
2045 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab_instance->traceset_info->
2046 traceset_context));
2047 g_object_unref(tab_instance->traceset_info->traceset_context);
2048 }
2049 if(tab_instance->traceset_info->traceset != NULL) {
2050 nb = lttv_traceset_number(tab_instance->traceset_info->traceset);
2051 for(i = 0 ; i < nb ; i++) {
2052 trace = lttv_traceset_get(tab_instance->traceset_info->traceset, i);
2053 ref_count = lttv_trace_get_ref_number(trace);
2054 if(ref_count <= 1){
2055 ltt_trace_close(lttv_trace(trace));
2056 lttv_trace_destroy(trace);
2057 }
2058 // lttv_trace_destroy(trace);
2059 }
2060 }
2061 lttv_traceset_destroy(tab_instance->traceset_info->traceset);
2062 g_array_free(tab_instance->time_requests, TRUE);
2063 g_free(tab_instance->traceset_info);
2064 g_free(tab_instance);
2065}
2066
2067
2068/* Create a tab and insert it into the current main window
2069 */
2070
2071void * create_tab(MainWindow * parent, MainWindow* current_window,
2072 GtkNotebook * notebook, char * label)
2073{
2074 GList * list;
2075 Tab * tmp_tab;
2076 MainWindow * mw_data = current_window;
2077 LttTime tmp_time;
2078
2079 //create a new tab data structure
2080 tmp_tab = mw_data->tab;
2081 while(tmp_tab && tmp_tab->next) tmp_tab = tmp_tab->next;
2082 if(!tmp_tab){
2083 mw_data->current_tab = NULL;
2084 tmp_tab = g_new(Tab,1);
2085 mw_data->tab = tmp_tab;
2086 }else{
2087 tmp_tab->next = g_new(Tab,1);
2088 tmp_tab = tmp_tab->next;
2089 }
2090
2091 //construct and initialize the traceset_info
2092 tmp_tab->traceset_info = g_new(TracesetInfo,1);
2093 if(parent){
2094 if(parent->current_tab){
2095 tmp_tab->traceset_info->traceset =
2096 lttv_traceset_new();
2097 //FIXME lttv_traceset_copy(parent->current_tab->traceset_info->traceset);
2098 }else{
2099 tmp_tab->traceset_info->traceset = lttv_traceset_new();
2100 }
2101
2102 }else{ /* Initial window */
2103 if(mw_data->current_tab){
2104 tmp_tab->traceset_info->traceset =
2105 lttv_traceset_new();
2106 //FIXME lttv_traceset_copy(mw_data->current_tab->traceset_info->traceset);
2107 }else{
2108 tmp_tab->traceset_info->traceset = lttv_traceset_new();
2109 /* Add the command line trace */
2110 if(g_init_trace != NULL){
2111 lttv_traceset_add(tmp_tab->traceset_info->traceset, g_init_trace);
2112 }
2113 }
2114 }
2115
2116 //FIXME copy not implemented in lower level
2117 tmp_tab->traceset_info->traceset_context =
2118 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
2119 g_assert(tmp_tab->traceset_info->traceset_context != NULL);
2120 lttv_context_init(
2121 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context),
2122 tmp_tab->traceset_info->traceset);
2123 //add state update hooks
2124 lttv_state_add_event_hooks(
2125 (LttvTracesetState*)tmp_tab->traceset_info->traceset_context);
2126
2127 //determine the current_time and time_window of the tab
2128 if(mw_data->current_tab){
2129 // Will have to read directly at the main window level, as we want
2130 // to be able to modify a traceset on the fly.
2131 tmp_tab->time_window = mw_data->current_tab->time_window;
2132 tmp_tab->current_time = mw_data->current_tab->current_time;
2133 }else{
2134 // Will have to read directly at the main window level, as we want
2135 // to be able to modify a traceset on the fly.
2136 // get_traceset_time_span(mw_data,&tmp_tab->traceStartTime, &tmp_tab->traceEndTime);
2137 tmp_tab->time_window.start_time =
2138 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->startTime;
2139 if(DEFAULT_TIME_WIDTH_S <
2140 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->endTime.tv_sec)
2141 tmp_time.tv_sec = DEFAULT_TIME_WIDTH_S;
2142 else
2143 tmp_time.tv_sec =
2144 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->endTime.tv_sec;
2145 tmp_time.tv_nsec = 0;
2146 tmp_tab->time_window.time_width = tmp_time ;
2147 tmp_tab->current_time.tv_sec =
2148 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->startTime.tv_sec;
2149 tmp_tab->current_time.tv_nsec =
2150 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->startTime.tv_nsec;
2151 }
2152 /* Become the current tab */
2153 mw_data->current_tab = tmp_tab;
2154
2155 tmp_tab->attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
2156 tmp_tab->multi_vpaned = (GtkMultiVPaned*)gtk_multi_vpaned_new();
2157 tmp_tab->multi_vpaned->mw = mw_data;
2158 gtk_widget_show((GtkWidget*)tmp_tab->multi_vpaned);
2159 tmp_tab->next = NULL;
2160 tmp_tab->mw = mw_data;
2161
2162 tmp_tab->label = gtk_label_new (label);
2163 gtk_widget_show (tmp_tab->label);
2164
2165 tmp_tab->time_requests = g_array_new(FALSE, FALSE, sizeof(TimeRequest));
2166 tmp_tab->time_request_pending = FALSE;
2167
2168 g_object_set_data_full(
2169 G_OBJECT(tmp_tab->multi_vpaned),
2170 "Tab_Info",
2171 tmp_tab,
2172 (GDestroyNotify)tab_destructor);
2173
2174 //insert tab into notebook
2175 gtk_notebook_append_page(notebook, (GtkWidget*)tmp_tab->multi_vpaned, tmp_tab->label);
2176 list = gtk_container_get_children(GTK_CONTAINER(notebook));
2177 gtk_notebook_set_current_page(notebook,g_list_length(list)-1);
2178 // always show : not if(g_list_length(list)>1)
2179 gtk_notebook_set_show_tabs(notebook, TRUE);
2180
2181}
2182
2183
2184/* Remove menu entry and tool button from main window for the
2185 * unloaded module
2186 */
2187
2188void remove_menu_item(gpointer main_win, gpointer user_data)
2189{
2190 MainWindow * mw = (MainWindow *) main_win;
2191 lttv_menu_closure *menu_item = (lttv_menu_closure *)user_data;
2192 GtkWidget * tool_menu_title_menu, *insert_view;
2193
2194 tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
2195 insert_view = (GtkWidget*)g_hash_table_lookup(mw->hash_menu_item,
2196 menu_item->menuText);
2197 if(insert_view){
2198 g_hash_table_remove(mw->hash_menu_item, menu_item->menuText);
2199 gtk_container_remove (GTK_CONTAINER (tool_menu_title_menu), insert_view);
2200 }
2201}
2202
2203void remove_toolbar_item(gpointer main_win, gpointer user_data)
2204{
2205 MainWindow * mw = (MainWindow *) main_win;
2206 lttv_toolbar_closure *toolbar_item = (lttv_toolbar_closure *)user_data;
2207 GtkWidget * tool_menu_title_menu, *insert_view;
2208
2209
2210 tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1");
2211 insert_view = (GtkWidget*)g_hash_table_lookup(mw->hash_toolbar_item,
2212 toolbar_item->tooltip);
2213 if(insert_view){
2214 g_hash_table_remove(mw->hash_toolbar_item, toolbar_item->tooltip);
2215 gtk_container_remove (GTK_CONTAINER (tool_menu_title_menu), insert_view);
2216 }
2217}
2218
2219/**
2220 * Remove menu and toolbar item when a module unloaded from all
2221 * main windows
2222 */
2223
2224void main_window_remove_menu_item(lttvwindow_viewer_constructor constructor)
2225{
2226 int i;
2227 LttvMenus * menu;
2228 lttv_menu_closure *menu_item;
2229 LttvAttributeValue value;
2230 LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
2231
2232 g_assert(lttv_iattribute_find_by_path(attributes,
2233 "viewers/menu", LTTV_POINTER, &value));
2234 menu = (LttvMenus*)*(value.v_pointer);
2235
2236 if(menu){
2237 for(i=0;i<menu->len;i++){
2238 menu_item = &g_array_index(menu, lttv_menu_closure, i);
2239 if(menu_item->con != constructor) continue;
2240 if(g_main_window_list){
2241 g_slist_foreach(g_main_window_list, remove_menu_item, menu_item);
2242 }
2243 break;
2244 }
2245 }
2246
2247}
2248
2249void main_window_remove_toolbar_item(lttvwindow_viewer_constructor constructor)
2250{
2251 int i;
2252 LttvToolbars * toolbar;
2253 lttv_toolbar_closure *toolbar_item;
2254 LttvAttributeValue value;
2255 LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
2256
2257 g_assert(lttv_iattribute_find_by_path(attributes,
2258 "viewers/toolbar", LTTV_POINTER, &value));
2259 toolbar = (LttvToolbars*)*(value.v_pointer);
2260
2261 if(toolbar){
2262 for(i=0;i<toolbar->len;i++){
2263 toolbar_item = &g_array_index(toolbar, lttv_toolbar_closure, i);
2264 if(toolbar_item->con != constructor) continue;
2265 if(g_main_window_list){
2266 g_slist_foreach(g_main_window_list, remove_toolbar_item, toolbar_item);
2267 }
2268 break;
2269 }
2270 }
2271}
2272
2273/**
2274 * Function to show each viewer in the current tab.
2275 * It will be called by main window, call show on each registered viewer,
2276 * will call process traceset and then it will
2277 * @param main_win the main window the viewer belongs to.
2278 */
2279//FIXME Only one time request maximum for now!
2280void show_viewer(MainWindow *main_win)
2281{
2282 LttvAttributeValue value;
2283 LttvHooks * tmp;
2284 int i;
2285 LttvTracesetContext * tsc =
2286 (LttvTracesetContext*)main_win->current_tab->
2287 traceset_info->traceset_context;
2288
2289 g_assert(lttv_iattribute_find_by_path(main_win->current_tab->attributes,
2290 "hooks/showviewer", LTTV_POINTER, &value));
2291 tmp = (LttvHooks*)*(value.v_pointer);
2292 if(tmp == NULL)
2293 {
2294 g_warning("The viewer(s) did not add any show hook");
2295 return;
2296 }
2297
2298
2299 // Call the show, where viewers add hooks to context and fill the
2300 // time and number of events requested it the time_requests GArray.
2301 lttv_hooks_call(tmp, NULL);
2302
2303
2304}
2305
2306
2307gboolean execute_time_requests(MainWindow * mw)
2308{
2309 call_pending_read_hooks(mw);
2310
2311 return FALSE; // automatically removed from the list of event sources
2312}
2313
This page took 0.029795 seconds and 4 git commands to generate.