tim seek work with state, interrupt disabled
[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 <limits.h> // for PATH_MAX
24 #include <stdlib.h>
25
26 #include <gtk/gtk.h>
27
28 #include "callbacks.h"
29 #include "interface.h"
30 #include "support.h"
31 #include <ltt/trace.h>
32 #include <ltt/facility.h>
33 #include <ltt/time.h>
34 #include <ltt/event.h>
35 #include <lttv/lttv.h>
36 #include <lttv/module.h>
37 #include <lttv/iattribute.h>
38 #include <lttv/stats.h>
39 #include <lttvwindow/mainwindow.h>
40 #include <lttvwindow/mainwindow-private.h>
41 #include <lttvwindow/menu.h>
42 #include <lttvwindow/toolbar.h>
43 #include <lttvwindow/lttvwindow.h>
44 #include <lttvwindow/lttvwindowtraces.h>
45 #include <lttvwindow/gtkdirsel.h>
46 #include <lttvwindow/lttvfilter.h>
47
48
49 #define DEFAULT_TIME_WIDTH_S 1
50
51 extern LttvTrace *g_init_trace ;
52
53
54 /** Array containing instanced objects. */
55 extern GSList * g_main_window_list;
56
57 /** MD : keep old directory. */
58 static char remember_plugins_dir[PATH_MAX] = "";
59 static char remember_trace_dir[PATH_MAX] = "";
60
61
62 MainWindow * get_window_data_struct(GtkWidget * widget);
63 char * get_unload_module(char ** loaded_module_name, int nb_module);
64 char * get_remove_trace(char ** all_trace_name, int nb_trace);
65 char * get_selection(char ** all_name, int nb, char *title, char * column_title);
66 gboolean get_filter_selection(LttvTracesetSelector *s, char *title, char * column_title);
67 Tab* create_tab(MainWindow * mw, Tab *copy_tab,
68 GtkNotebook * notebook, char * label);
69
70 static void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor);
71 void update_filter(LttvTracesetSelector *s, GtkTreeStore *store );
72
73 void checkbox_changed(GtkTreeView *treeview,
74 GtkTreePath *arg1,
75 GtkTreeViewColumn *arg2,
76 gpointer user_data);
77 void remove_trace_from_traceset_selector(GtkMultiVPaned * paned, unsigned i);
78 void add_trace_into_traceset_selector(GtkMultiVPaned * paned, LttTrace * trace);
79 Tab *create_new_tab(GtkWidget* widget, gpointer user_data);
80
81 LttvTracesetSelector * construct_traceset_selector(LttvTraceset * traceset);
82
83 static gboolean lttvwindow_process_pending_requests(Tab *tab);
84
85 enum {
86 CHECKBOX_COLUMN,
87 NAME_COLUMN,
88 TOTAL_COLUMNS
89 };
90
91 enum
92 {
93 MODULE_COLUMN,
94 N_COLUMNS
95 };
96
97 /* Construct a selector(filter), which will be associated with a viewer,
98 * and provides an interface for user to select interested events and traces
99 */
100
101 LttvTracesetSelector * construct_traceset_selector(LttvTraceset * traceset)
102 {
103 LttvTracesetSelector * s;
104 LttvTraceSelector * trace;
105 LttvTracefileSelector * tracefile;
106 LttvEventtypeSelector * eventtype;
107 int i, j, k, m;
108 int nb_trace, nb_tracefile, nb_control, nb_per_cpu, nb_facility, nb_event;
109 LttvTrace * trace_v;
110 LttTrace * t;
111 LttTracefile *tf;
112 LttFacility * fac;
113 LttEventType * et;
114
115 s = lttv_traceset_selector_new(lttv_traceset_name(traceset));
116 nb_trace = lttv_traceset_number(traceset);
117 for(i=0;i<nb_trace;i++){
118 trace_v = lttv_traceset_get(traceset, i);
119 t = lttv_trace(trace_v);
120 trace = lttv_trace_selector_new(t);
121 lttv_traceset_selector_trace_add(s, trace);
122
123 nb_facility = ltt_trace_facility_number(t);
124 for(k=0;k<nb_facility;k++){
125 fac = ltt_trace_facility_get(t,k);
126 nb_event = (int) ltt_facility_eventtype_number(fac);
127 for(m=0;m<nb_event;m++){
128 et = ltt_facility_eventtype_get(fac,m);
129 eventtype = lttv_eventtype_selector_new(et);
130 lttv_trace_selector_eventtype_add(trace, eventtype);
131 }
132 }
133
134 nb_control = ltt_trace_control_tracefile_number(t);
135 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(t);
136 nb_tracefile = nb_control + nb_per_cpu;
137
138 for(j = 0 ; j < nb_tracefile ; j++) {
139 if(j < nb_control)
140 tf = ltt_trace_control_tracefile_get(t, j);
141 else
142 tf = ltt_trace_per_cpu_tracefile_get(t, j - nb_control);
143 tracefile = lttv_tracefile_selector_new(tf);
144 lttv_trace_selector_tracefile_add(trace, tracefile);
145 lttv_eventtype_selector_copy(trace, tracefile);
146 }
147 }
148 return s;
149 }
150
151
152 /* insert_viewer function constructs an instance of a viewer first,
153 * then inserts the widget of the instance into the container of the
154 * main window
155 */
156
157 void
158 insert_viewer_wrap(GtkWidget *menuitem, gpointer user_data)
159 {
160 guint val = 20;
161
162 insert_viewer((GtkWidget*)menuitem, (lttvwindow_viewer_constructor)user_data);
163 // selected_hook(&val);
164 }
165
166
167 /* internal functions */
168 void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor)
169 {
170 GtkMultiVPaned * multi_vpaned;
171 MainWindow * mw_data = get_window_data_struct(widget);
172 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
173 GtkWidget * viewer;
174 LttvTracesetSelector * s;
175 TimeInterval * time_interval;
176 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
177 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
178 Tab *tab;
179
180 if(!page) {
181 tab = create_new_tab(widget, NULL);
182 } else {
183 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
184 }
185
186 multi_vpaned = tab->multi_vpaned;
187
188 s = construct_traceset_selector(tab->traceset_info->traceset);
189 viewer = (GtkWidget*)constructor(tab, s, "Traceset_Selector");
190 if(viewer)
191 {
192 gtk_multi_vpaned_widget_add(multi_vpaned, viewer);
193 // We unref here, because it is now referenced by the multi_vpaned!
194 g_object_unref(G_OBJECT(viewer));
195
196 // The viewer will show itself when it receives a show notify
197 // So we call the show notify hooks here. It will
198 // typically add hooks for reading, we call process trace, and the
199 // end of reading hook will call gtk_widget_show and unregister the
200 // hooks.
201 // Note that show notify gets the time_requested through the call_data.
202 //show_viewer(mw_data);
203 // in expose now call_pending_read_hooks(mw_data);
204 }
205 }
206
207
208 /* get_label function is used to get user input, it displays an input
209 * box, which allows user to input a string
210 */
211
212 void get_label_string (GtkWidget * text, gchar * label)
213 {
214 GtkEntry * entry = (GtkEntry*)text;
215 if(strlen(gtk_entry_get_text(entry))!=0)
216 strcpy(label,gtk_entry_get_text(entry));
217 }
218
219 gboolean get_label(MainWindow * mw, gchar * str, gchar* dialogue_title, gchar * label_str)
220 {
221 GtkWidget * dialogue;
222 GtkWidget * text;
223 GtkWidget * label;
224 gint id;
225
226 dialogue = gtk_dialog_new_with_buttons(dialogue_title,NULL,
227 GTK_DIALOG_MODAL,
228 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
229 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
230 NULL);
231
232 label = gtk_label_new(label_str);
233 gtk_widget_show(label);
234
235 text = gtk_entry_new();
236 gtk_widget_show(text);
237
238 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), label,TRUE, TRUE,0);
239 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), text,FALSE, FALSE,0);
240
241 id = gtk_dialog_run(GTK_DIALOG(dialogue));
242 switch(id){
243 case GTK_RESPONSE_ACCEPT:
244 get_label_string(text,str);
245 gtk_widget_destroy(dialogue);
246 break;
247 case GTK_RESPONSE_REJECT:
248 default:
249 gtk_widget_destroy(dialogue);
250 return FALSE;
251 }
252 return TRUE;
253 }
254
255
256 /* get_window_data_struct function is actually a lookup function,
257 * given a widget which is in the tree of the main window, it will
258 * return the MainWindow data structure associated with main window
259 */
260
261 MainWindow * get_window_data_struct(GtkWidget * widget)
262 {
263 GtkWidget * mw;
264 MainWindow * mw_data;
265
266 mw = lookup_widget(widget, "MWindow");
267 if(mw == NULL){
268 g_printf("Main window does not exist\n");
269 return NULL;
270 }
271
272 mw_data = (MainWindow *) g_object_get_data(G_OBJECT(mw),"main_window_data");
273 if(mw_data == NULL){
274 g_printf("Main window data does not exist\n");
275 return NULL;
276 }
277 return mw_data;
278 }
279
280
281 /* create_new_window function, just constructs a new main window
282 */
283
284 void create_new_window(GtkWidget* widget, gpointer user_data, gboolean clone)
285 {
286 MainWindow * parent = get_window_data_struct(widget);
287
288 if(clone){
289 g_printf("Clone : use the same traceset\n");
290 construct_main_window(parent);
291 }else{
292 g_printf("Empty : traceset is set to NULL\n");
293 construct_main_window(NULL);
294 }
295 }
296
297
298 /* move_*_viewer functions move the selected view up/down in
299 * the current tab
300 */
301
302 void move_up_viewer(GtkWidget * widget, gpointer user_data)
303 {
304 MainWindow * mw = get_window_data_struct(widget);
305 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
306
307 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
308 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
309
310 Tab *tab;
311
312 if(!page) {
313 return;
314 } else {
315 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
316 }
317
318 gtk_multi_vpaned_widget_move_up(tab->multi_vpaned);
319 }
320
321 void move_down_viewer(GtkWidget * widget, gpointer user_data)
322 {
323 MainWindow * mw = get_window_data_struct(widget);
324 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
325
326 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
327 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
328 Tab *tab;
329
330 if(!page) {
331 return;
332 } else {
333 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
334 }
335
336 gtk_multi_vpaned_widget_move_down(tab->multi_vpaned);
337 }
338
339
340 /* delete_viewer deletes the selected viewer in the current tab
341 */
342
343 void delete_viewer(GtkWidget * widget, gpointer user_data)
344 {
345 MainWindow * mw = get_window_data_struct(widget);
346 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
347
348 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
349 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
350 Tab *tab;
351
352 if(!page) {
353 return;
354 } else {
355 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
356 }
357
358 gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
359 }
360
361
362 /* open_traceset will open a traceset saved in a file
363 * Right now, it is not finished yet, (not working)
364 * FIXME
365 */
366
367 void open_traceset(GtkWidget * widget, gpointer user_data)
368 {
369 char ** dir;
370 gint id;
371 LttvTraceset * traceset;
372 MainWindow * mw_data = get_window_data_struct(widget);
373 GtkFileSelection * file_selector =
374 (GtkFileSelection *)gtk_file_selection_new("Select a traceset");
375
376 gtk_file_selection_hide_fileop_buttons(file_selector);
377
378 id = gtk_dialog_run(GTK_DIALOG(file_selector));
379 switch(id){
380 case GTK_RESPONSE_ACCEPT:
381 case GTK_RESPONSE_OK:
382 dir = gtk_file_selection_get_selections (file_selector);
383 traceset = lttv_traceset_load(dir[0]);
384 g_printf("Open a trace set %s\n", dir[0]);
385 //Not finished yet
386 g_strfreev(dir);
387 case GTK_RESPONSE_REJECT:
388 case GTK_RESPONSE_CANCEL:
389 default:
390 gtk_widget_destroy((GtkWidget*)file_selector);
391 break;
392 }
393
394 }
395
396
397 /* lttvwindow_process_pending_requests
398 *
399 * This internal function gets called by g_idle, taking care of the pending
400 * requests. It is responsible for concatenation of time intervals and position
401 * requests. It does it with the following algorithm organizing process traceset
402 * calls. Here is the detailed description of the way it works :
403 *
404 * - Events Requests Servicing Algorithm
405 *
406 * Data structures necessary :
407 *
408 * List of requests added to context : list_in
409 * List of requests not added to context : list_out
410 *
411 * Initial state :
412 *
413 * list_in : empty
414 * list_out : many events requests
415 *
416 * FIXME : insert rest of algorithm here
417 *
418 */
419
420 #define list_out tab->events_requests
421
422 gboolean lttvwindow_process_pending_requests(Tab *tab)
423 {
424 unsigned max_nb_events;
425 GdkWindow * win;
426 GdkCursor * new;
427 GtkWidget* widget;
428 LttvTracesetContext *tsc;
429 LttvTracefileContext *tfc;
430 GSList *list_in = NULL;
431 LttTime end_time;
432 guint end_nb_events;
433 guint count;
434 LttvTracesetContextPosition *end_position;
435
436 if(tab == NULL)
437 return FALSE;
438
439 /* There is no events requests pending : we should never have been called! */
440 g_assert(g_slist_length(list_out) != 0);
441
442 tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
443
444 //set the cursor to be X shape, indicating that the computer is busy in doing its job
445 new = gdk_cursor_new(GDK_X_CURSOR);
446 widget = lookup_widget(tab->mw->mwindow, "MToolbar1");
447 win = gtk_widget_get_parent_window(widget);
448 gdk_window_set_cursor(win, new);
449 gdk_cursor_unref(new);
450 gdk_window_stick(win);
451 gdk_window_unstick(win);
452
453 g_debug("SIZE events req len : %d", g_slist_length(list_out));
454
455 /* Preliminary check for no trace in traceset */
456 /* Unregister the routine if empty, empty list_out too */
457 if(lttv_traceset_number(tsc->ts) == 0) {
458
459 /* - For each req in list_out */
460 GSList *iter = list_out;
461
462 while(iter != NULL) {
463
464 gboolean remove = FALSE;
465 gboolean free_data = FALSE;
466 EventsRequest *events_request = (EventsRequest *)iter->data;
467
468 /* - Call end request for req */
469 if(events_request->servicing == TRUE)
470 lttv_hooks_call(events_request->after_request, (gpointer)tsc);
471
472 /* - remove req from list_out */
473 /* Destroy the request */
474 remove = TRUE;
475 free_data = TRUE;
476
477 /* Go to next */
478 if(remove)
479 {
480 GSList *remove_iter = iter;
481
482 iter = g_slist_next(iter);
483 if(free_data) g_free(remove_iter->data);
484 list_out = g_slist_remove_link(list_out, remove_iter);
485 } else { // not remove
486 iter = g_slist_next(iter);
487 }
488 }
489 }
490
491 /* Events processing algorithm implementation */
492 /* A. Servicing loop */
493 while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
494 /* && !gtk_events_pending() ) */
495
496 /* 1. If list_in is empty (need a seek) */
497 if( g_slist_length(list_in) == 0 ) {
498
499 /* list in is empty, need a seek */
500 {
501 /* 1.1 Add requests to list_in */
502 GSList *ltime = NULL;
503 GSList *lpos = NULL;
504 GSList *iter = NULL;
505
506 /* 1.1.1 Find all time requests with the lowest start time in list_out
507 * (ltime)
508 */
509 if(g_slist_length(list_out) > 0)
510 ltime = g_slist_append(ltime, g_slist_nth_data(list_out, 0));
511 for(iter=g_slist_nth(list_out,1);iter!=NULL;iter=g_slist_next(iter)) {
512 /* Find all time requests with the lowest start time in list_out */
513 guint index_ltime = g_array_index(ltime, guint, 0);
514 EventsRequest *event_request_ltime = (EventsRequest*)g_slist_nth_data(ltime, 0);
515 EventsRequest *event_request_list_out = (EventsRequest*)iter->data;
516
517 int comp;
518 comp = ltt_time_compare(event_request_ltime->start_time,
519 event_request_list_out->start_time);
520 if(comp == 0)
521 ltime = g_slist_append(ltime, event_request_list_out);
522 else if(comp > 0) {
523 /* Remove all elements from ltime, and add current */
524 while(ltime != NULL)
525 ltime = g_slist_delete_link(ltime, g_slist_nth(ltime, 0));
526 ltime = g_slist_append(ltime, event_request_list_out);
527 }
528 }
529
530 /* 1.1.2 Find all position requests with the lowest position in list_out
531 * (lpos)
532 */
533 if(g_slist_length(list_out) > 0)
534 lpos = g_slist_append(lpos, g_slist_nth_data(list_out, 0));
535 for(iter=g_slist_nth(list_out,1);iter!=NULL;iter=g_slist_next(iter)) {
536 /* Find all position requests with the lowest position in list_out */
537 guint index_lpos = g_array_index(lpos, guint, 0);
538 EventsRequest *event_request_lpos = (EventsRequest*)g_slist_nth_data(lpos, 0);
539 EventsRequest *event_request_list_out = (EventsRequest*)iter->data;
540
541 int comp;
542 if(event_request_lpos->start_position != NULL
543 && event_request_list_out->start_position != NULL)
544 {
545 comp = lttv_traceset_context_pos_pos_compare
546 (event_request_lpos->start_position,
547 event_request_list_out->start_position);
548 } else {
549 comp = -1;
550 }
551 if(comp == 0)
552 lpos = g_slist_append(lpos, event_request_list_out);
553 else if(comp > 0) {
554 /* Remove all elements from lpos, and add current */
555 while(lpos != NULL)
556 lpos = g_slist_delete_link(lpos, g_slist_nth(lpos, 0));
557 lpos = g_slist_append(lpos, event_request_list_out);
558 }
559 }
560
561 /* 1.1.3 If lpos.start time < ltime */
562 {
563 EventsRequest *event_request_lpos = (EventsRequest*)g_slist_nth_data(lpos, 0);
564 EventsRequest *event_request_ltime = (EventsRequest*)g_slist_nth_data(ltime, 0);
565 LttTime lpos_start_time;
566
567 if(event_request_lpos != NULL
568 && event_request_lpos->start_position != NULL) {
569
570 lpos_start_time = lttv_traceset_context_position_get_time(
571 event_request_lpos->start_position);
572 if(ltt_time_compare(lpos_start_time,
573 event_request_ltime->start_time)<0) {
574 /* Add lpos to list_in, remove them from list_out */
575
576 for(iter=lpos;iter!=NULL;iter=g_slist_next(iter)) {
577 /* Add to list_in */
578 EventsRequest *event_request_lpos =
579 (EventsRequest*)iter->data;
580
581 list_in = g_slist_append(list_in, event_request_lpos);
582 /* Remove from list_out */
583 list_out = g_slist_remove(list_out, event_request_lpos);
584 }
585 }
586 } else {
587 /* 1.1.4 (lpos.start time >= ltime) */
588 /* Add ltime to list_in, remove them from list_out */
589
590 for(iter=ltime;iter!=NULL;iter=g_slist_next(iter)) {
591 /* Add to list_in */
592 EventsRequest *event_request_ltime =
593 (EventsRequest*)iter->data;
594
595 list_in = g_slist_append(list_in, event_request_ltime);
596 /* Remove from list_out */
597 list_out = g_slist_remove(list_out, event_request_ltime);
598 }
599 }
600 }
601 g_slist_free(lpos);
602 g_slist_free(ltime);
603 }
604
605 /* 1.2 Seek */
606 {
607 tfc = lttv_traceset_context_get_current_tfc(tsc);
608 g_assert(g_slist_length(list_in)>0);
609 EventsRequest *events_request = g_slist_nth_data(list_in, 0);
610 guint seek_count;
611
612 /* 1.2.1 If first request in list_in is a time request */
613 if(events_request->start_position == NULL) {
614 /* - If first req in list_in start time != current time */
615 if(tfc == NULL || ltt_time_compare(events_request->start_time,
616 tfc->timestamp) != 0)
617 /* - Seek to that time */
618 g_debug("SEEK TIME : %lu, %lu", events_request->start_time.tv_sec,
619 events_request->start_time.tv_nsec);
620 //lttv_process_traceset_seek_time(tsc, events_request->start_time);
621 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc),
622 events_request->start_time);
623
624 /* Process the traceset with only state hooks */
625 seek_count =
626 lttv_process_traceset_middle(tsc,
627 events_request->start_time,
628 G_MAXUINT, NULL);
629
630
631 } else {
632 LttTime pos_time;
633 /* Else, the first request in list_in is a position request */
634 /* If first req in list_in pos != current pos */
635 g_assert(events_request->start_position != NULL);
636 if(lttv_traceset_context_ctx_pos_compare(tsc,
637 events_request->start_position) != 0) {
638 /* 1.2.2.1 Seek to that position */
639 g_debug("SEEK POSITION");
640 //lttv_process_traceset_seek_position(tsc, events_request->start_position);
641 pos_time = lttv_traceset_context_position_get_time(events_request->start_position);
642
643 lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc),
644 pos_time);
645
646 /* Process the traceset with only state hooks */
647 seek_count =
648 lttv_process_traceset_middle(tsc,
649 ltt_time_infinite,
650 G_MAXUINT,
651 events_request->start_position);
652
653
654 }
655 }
656 }
657
658 /* 1.3 Add hooks and call before request for all list_in members */
659 {
660 GSList *iter = NULL;
661
662 for(iter=list_in;iter!=NULL;iter=g_slist_next(iter)) {
663 EventsRequest *events_request = (EventsRequest*)iter->data;
664 /* 1.3.1 If !servicing */
665 if(events_request->servicing == FALSE) {
666 /* - begin request hooks called
667 * - servicing = TRUE
668 */
669 lttv_hooks_call(events_request->before_request, (gpointer)tsc);
670 events_request->servicing = TRUE;
671 }
672 /* 1.3.2 call before chunk
673 * 1.3.3 events hooks added
674 */
675 lttv_process_traceset_begin(tsc, events_request->before_chunk_traceset,
676 events_request->before_chunk_trace,
677 events_request->before_chunk_tracefile,
678 events_request->event,
679 events_request->event_by_id);
680 }
681 }
682 } else {
683 /* 2. Else, list_in is not empty, we continue a read */
684
685 {
686 /* 2.0 For each req of list_in */
687 GSList *iter = list_in;
688
689 while(iter != NULL) {
690
691 EventsRequest *events_request = (EventsRequest *)iter->data;
692
693 /* - Call before chunk
694 * - events hooks added
695 */
696 lttv_process_traceset_begin(tsc, events_request->before_chunk_traceset,
697 events_request->before_chunk_trace,
698 events_request->before_chunk_tracefile,
699 events_request->event,
700 events_request->event_by_id);
701
702 iter = g_slist_next(iter);
703 }
704 }
705
706 {
707 GSList *iter = NULL;
708 tfc = lttv_traceset_context_get_current_tfc(tsc);
709
710 /* 2.1 For each req of list_out */
711 for(iter=list_out;iter!=NULL;iter=g_slist_next(iter)) {
712 EventsRequest *events_request = (EventsRequest*)iter->data;
713
714 /* if req.start time == current context time
715 * or req.start position == current position*/
716 if( ltt_time_compare(events_request->start_time,
717 tfc->timestamp) == 0
718 ||
719 (events_request->start_position != NULL
720 &&
721 lttv_traceset_context_ctx_pos_compare(tsc,
722 events_request->start_position) == 0)
723 ) {
724 /* - Add to list_in, remove from list_out */
725 list_in = g_slist_append(list_in, events_request);
726 list_out = g_slist_remove(list_out, events_request);
727
728 /* - If !servicing */
729 if(events_request->servicing == FALSE) {
730 /* - begin request hooks called
731 * - servicing = TRUE
732 */
733 lttv_hooks_call(events_request->before_request, (gpointer)tsc);
734 events_request->servicing = TRUE;
735 }
736 /* call before chunk
737 * events hooks added
738 */
739 lttv_process_traceset_begin(tsc, events_request->before_chunk_traceset,
740 events_request->before_chunk_trace,
741 events_request->before_chunk_tracefile,
742 events_request->event,
743 events_request->event_by_id);
744 }
745 }
746 }
747 }
748
749 /* 3. Find end criterions */
750 {
751 /* 3.1 End time */
752 GSList *iter;
753
754 /* 3.1.1 Find lowest end time in list_in */
755 g_assert(g_slist_length(list_in)>0);
756 end_time = ((EventsRequest*)g_slist_nth_data(list_in,0))->end_time;
757
758 for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) {
759 EventsRequest *events_request = (EventsRequest*)iter->data;
760
761 if(ltt_time_compare(events_request->end_time,
762 end_time) < 0)
763 end_time = events_request->end_time;
764 }
765
766 /* 3.1.2 Find lowest start time in list_out */
767 for(iter=list_out;iter!=NULL;iter=g_slist_next(iter)) {
768 EventsRequest *events_request = (EventsRequest*)iter->data;
769
770 if(ltt_time_compare(events_request->start_time,
771 end_time) < 0)
772 end_time = events_request->start_time;
773 }
774 }
775
776 {
777 /* 3.2 Number of events */
778
779 /* 3.2.1 Find lowest number of events in list_in */
780 GSList *iter;
781
782 end_nb_events = ((EventsRequest*)g_slist_nth_data(list_in,0))->num_events;
783
784 for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) {
785 EventsRequest *events_request = (EventsRequest*)iter->data;
786
787 if(events_request->num_events < end_nb_events)
788 end_nb_events = events_request->num_events;
789 }
790
791 /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
792 * num_events */
793
794 end_nb_events = MIN(CHUNK_NUM_EVENTS, end_nb_events);
795 }
796
797 {
798 /* 3.3 End position */
799
800 /* 3.3.1 Find lowest end position in list_in */
801 GSList *iter;
802
803 end_position =((EventsRequest*)g_slist_nth_data(list_in,0))->end_position;
804
805 for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) {
806 EventsRequest *events_request = (EventsRequest*)iter->data;
807
808 if(events_request->end_position != NULL && end_position != NULL &&
809 lttv_traceset_context_pos_pos_compare(events_request->end_position,
810 end_position) <0)
811 end_position = events_request->end_position;
812 }
813 }
814
815 {
816 /* 3.3.2 Find lowest start position in list_out */
817 GSList *iter;
818
819 for(iter=list_out;iter!=NULL;iter=g_slist_next(iter)) {
820 EventsRequest *events_request = (EventsRequest*)iter->data;
821
822 if(events_request->end_position != NULL && end_position != NULL &&
823 lttv_traceset_context_pos_pos_compare(events_request->end_position,
824 end_position) <0)
825 end_position = events_request->end_position;
826 }
827 }
828
829 {
830 /* 4. Call process traceset middle */
831 g_critical("Calling process traceset middle with %p, %lu sec %lu nsec, %lu nb ev, %p end pos", tsc, end_time.tv_sec, end_time.tv_nsec, end_nb_events, end_position);
832 count = lttv_process_traceset_middle(tsc, end_time, end_nb_events, end_position);
833
834 tfc = lttv_traceset_context_get_current_tfc(tsc);
835 g_critical("Context time after middle : %lu, %lu", tfc->timestamp.tv_sec,
836 tfc->timestamp.tv_nsec);
837
838 }
839 {
840 /* 5. After process traceset middle */
841 tfc = lttv_traceset_context_get_current_tfc(tsc);
842
843 /* - if current context time > traceset.end time */
844 if(tfc == NULL || ltt_time_compare(tfc->timestamp,
845 tsc->time_span.end_time) > 0) {
846 /* - For each req in list_in */
847 GSList *iter = list_in;
848
849 while(iter != NULL) {
850
851 gboolean remove = FALSE;
852 gboolean free_data = FALSE;
853 EventsRequest *events_request = (EventsRequest *)iter->data;
854
855 /* - Remove events hooks for req
856 * - Call end chunk for req
857 */
858 lttv_process_traceset_end(tsc, events_request->after_chunk_traceset,
859 events_request->after_chunk_trace,
860 events_request->after_chunk_tracefile,
861 events_request->event,
862 events_request->event_by_id);
863 /* - Call end request for req */
864 lttv_hooks_call(events_request->after_request, (gpointer)tsc);
865
866 /* - remove req from list_in */
867 /* Destroy the request */
868 remove = TRUE;
869 free_data = TRUE;
870
871 /* Go to next */
872 if(remove)
873 {
874 GSList *remove_iter = iter;
875
876 iter = g_slist_next(iter);
877 if(free_data) g_free(remove_iter->data);
878 list_in = g_slist_remove_link(list_in, remove_iter);
879 } else { // not remove
880 iter = g_slist_next(iter);
881 }
882 }
883 }
884 {
885 /* 5.1 For each req in list_in */
886 GSList *iter = list_in;
887
888 while(iter != NULL) {
889
890 gboolean remove = FALSE;
891 gboolean free_data = FALSE;
892 EventsRequest *events_request = (EventsRequest *)iter->data;
893
894 /* - Remove events hooks for req
895 * - Call end chunk for req
896 */
897 lttv_process_traceset_end(tsc, events_request->after_chunk_traceset,
898 events_request->after_chunk_trace,
899 events_request->after_chunk_tracefile,
900 events_request->event,
901 events_request->event_by_id);
902
903 /* - req.num -= count */
904 g_assert(events_request->num_events >= count);
905 events_request->num_events -= count;
906
907 g_assert(tfc != NULL);
908 /* - if req.num == 0
909 * or
910 * current context time >= req.end time
911 * or
912 * req.end pos == current pos
913 * or
914 * req.stop_flag == TRUE
915 */
916 if( events_request->num_events == 0
917 ||
918 events_request->stop_flag == TRUE
919 ||
920 ltt_time_compare(tfc->timestamp,
921 events_request->end_time) >= 0
922 ||
923 (events_request->start_position != NULL
924 &&
925 lttv_traceset_context_ctx_pos_compare(tsc,
926 events_request->start_position) != 0)
927
928 ) {
929 g_assert(events_request->servicing == TRUE);
930 /* - Call end request for req
931 * - remove req from list_in */
932 lttv_hooks_call(events_request->after_request, (gpointer)tsc);
933 /* - remove req from list_in */
934 /* Destroy the request */
935 remove = TRUE;
936 free_data = TRUE;
937 }
938
939 /* Go to next */
940 if(remove)
941 {
942 GSList *remove_iter = iter;
943
944 iter = g_slist_next(iter);
945 if(free_data) g_free(remove_iter->data);
946 list_in = g_slist_remove_link(list_in, remove_iter);
947 } else { // not remove
948 iter = g_slist_next(iter);
949 }
950 }
951 }
952 }
953
954 if(gtk_events_pending()) break;
955 }
956
957 /* B. When interrupted between chunks */
958
959 {
960 GSList *iter = list_in;
961
962 /* 1. for each request in list_in */
963 while(iter != NULL) {
964
965 gboolean remove = FALSE;
966 gboolean free_data = FALSE;
967 EventsRequest *events_request = (EventsRequest *)iter->data;
968
969 /* 1.1. Use current postition as start position */
970 if(events_request->start_position != NULL)
971 lttv_traceset_context_position_destroy(events_request->start_position);
972 events_request->start_position = ltt_traceset_context_position_new();
973 lttv_traceset_context_position_save(tsc, events_request->start_position);
974
975 /* 1.2. Remove start time */
976 events_request->start_time.tv_sec = G_MAXUINT;
977 events_request->start_time.tv_nsec = G_MAXUINT;
978
979 /* 1.3. Move from list_in to list_out */
980 remove = TRUE;
981 free_data = FALSE;
982 list_out = g_slist_append(list_out, events_request);
983
984 /* Go to next */
985 if(remove)
986 {
987 GSList *remove_iter = iter;
988
989 iter = g_slist_next(iter);
990 if(free_data) g_free(remove_iter->data);
991 list_in = g_slist_remove_link(list_in, remove_iter);
992 } else { // not remove
993 iter = g_slist_next(iter);
994 }
995 }
996
997
998 }
999
1000 //set the cursor back to normal
1001 gdk_window_set_cursor(win, NULL);
1002
1003
1004 g_assert(g_slist_length(list_in) == 0);
1005
1006 if( g_slist_length(list_out) == 0 ) {
1007 /* Put tab's request pending flag back to normal */
1008 tab->events_request_pending = FALSE;
1009 g_critical("remove the idle fct");
1010 return FALSE; /* Remove the idle function */
1011 }
1012 g_critical("leave the idle fct");
1013 return TRUE; /* Leave the idle function */
1014 }
1015
1016 #undef list_out
1017
1018
1019 /* add_trace_into_traceset_selector, each instance of a viewer has an associated
1020 * selector (filter), when a trace is added into traceset, the selector should
1021 * reflect the change. The function is used to update the selector
1022 */
1023
1024 void add_trace_into_traceset_selector(GtkMultiVPaned * paned, LttTrace * t)
1025 {
1026 int j, k, m, nb_tracefile, nb_control, nb_per_cpu, nb_facility, nb_event;
1027 LttvTracesetSelector * s;
1028 LttvTraceSelector * trace;
1029 LttvTracefileSelector * tracefile;
1030 LttvEventtypeSelector * eventtype;
1031 LttTracefile * tf;
1032 GtkWidget * w;
1033 LttFacility * fac;
1034 LttEventType * et;
1035
1036 w = gtk_multi_vpaned_get_first_widget(paned);
1037 while(w){
1038 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1039
1040 if(s){
1041 trace = lttv_trace_selector_new(t);
1042 lttv_traceset_selector_trace_add(s, trace);
1043
1044 nb_facility = ltt_trace_facility_number(t);
1045 for(k=0;k<nb_facility;k++){
1046 fac = ltt_trace_facility_get(t,k);
1047 nb_event = (int) ltt_facility_eventtype_number(fac);
1048 for(m=0;m<nb_event;m++){
1049 et = ltt_facility_eventtype_get(fac,m);
1050 eventtype = lttv_eventtype_selector_new(et);
1051 lttv_trace_selector_eventtype_add(trace, eventtype);
1052 }
1053 }
1054
1055 nb_control = ltt_trace_control_tracefile_number(t);
1056 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(t);
1057 nb_tracefile = nb_control + nb_per_cpu;
1058
1059 for(j = 0 ; j < nb_tracefile ; j++) {
1060 if(j < nb_control)
1061 tf = ltt_trace_control_tracefile_get(t, j);
1062 else
1063 tf = ltt_trace_per_cpu_tracefile_get(t, j - nb_control);
1064 tracefile = lttv_tracefile_selector_new(tf);
1065 lttv_trace_selector_tracefile_add(trace, tracefile);
1066 lttv_eventtype_selector_copy(trace, tracefile);
1067 }
1068 }else g_warning("Module does not support filtering\n");
1069
1070 w = gtk_multi_vpaned_get_next_widget(paned);
1071 }
1072 }
1073
1074
1075 static void lttvwindow_add_trace(Tab *tab, LttvTrace *trace_v)
1076 {
1077 LttvTraceset *traceset = tab->traceset_info->traceset;
1078 guint i;
1079
1080 //Verify if trace is already present.
1081 for(i=0; i<lttv_traceset_number(traceset); i++)
1082 {
1083 LttvTrace * trace = lttv_traceset_get(traceset, i);
1084 if(trace == trace_v)
1085 return;
1086 }
1087
1088 //Keep a reference to the traces so they are not freed.
1089 for(i=0; i<lttv_traceset_number(traceset); i++)
1090 {
1091 LttvTrace * trace = lttv_traceset_get(traceset, i);
1092 lttv_trace_ref(trace);
1093 }
1094
1095 //remove state update hooks
1096 lttv_state_remove_event_hooks(
1097 (LttvTracesetState*)tab->traceset_info->traceset_context);
1098
1099 lttv_context_fini(LTTV_TRACESET_CONTEXT(
1100 tab->traceset_info->traceset_context));
1101 g_object_unref(tab->traceset_info->traceset_context);
1102
1103 lttv_traceset_add(traceset, trace_v);
1104 lttv_trace_ref(trace_v); /* local ref */
1105
1106 /* Create new context */
1107 tab->traceset_info->traceset_context =
1108 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1109 lttv_context_init(
1110 LTTV_TRACESET_CONTEXT(tab->traceset_info->
1111 traceset_context),
1112 traceset);
1113
1114 /* Set the tab's time window and current time if currently 0, 0 */
1115 if(tab->time_window.start_time.tv_sec == 0 &&
1116 tab->time_window.start_time.tv_nsec == 0)
1117 tab->time_window.start_time =
1118 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
1119 time_span.start_time;
1120 if(tab->time_window.time_width.tv_sec == 0 &&
1121 tab->time_window.time_width.tv_nsec == 0) {
1122 LttTime tmp_time;
1123
1124 if(DEFAULT_TIME_WIDTH_S <
1125 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
1126 time_span.end_time.tv_sec)
1127 tmp_time.tv_sec = DEFAULT_TIME_WIDTH_S;
1128 else
1129 tmp_time.tv_sec =
1130 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
1131 time_span.end_time.tv_sec;
1132 tmp_time.tv_nsec = 0;
1133 tab->time_window.time_width = tmp_time ;
1134 }
1135 if(tab->current_time.tv_sec == 0 && tab->current_time.tv_nsec == 0) {
1136 tab->current_time.tv_sec =
1137 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
1138 time_span.start_time.tv_sec;
1139 tab->current_time.tv_nsec =
1140 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
1141 time_span.start_time.tv_nsec;
1142 }
1143
1144
1145 //add state update hooks
1146 lttv_state_add_event_hooks(
1147 (LttvTracesetState*)tab->traceset_info->traceset_context);
1148 //Remove local reference to the traces.
1149 for(i=0; i<lttv_traceset_number(traceset); i++)
1150 {
1151 LttvTrace * trace = lttv_traceset_get(traceset, i);
1152 lttv_trace_unref(trace);
1153 }
1154
1155 add_trace_into_traceset_selector(tab->multi_vpaned, lttv_trace(trace_v));
1156 }
1157
1158 /* add_trace adds a trace into the current traceset. It first displays a
1159 * directory selection dialogue to let user choose a trace, then recreates
1160 * tracset_context, and redraws all the viewer of the current tab
1161 */
1162
1163 void add_trace(GtkWidget * widget, gpointer user_data)
1164 {
1165 LttTrace *trace;
1166 LttvTrace * trace_v;
1167 LttvTraceset * traceset;
1168 const char * dir;
1169 char abs_path[PATH_MAX];
1170 gint id;
1171 gint i;
1172 MainWindow * mw_data = get_window_data_struct(widget);
1173 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1174
1175 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1176 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1177 Tab *tab;
1178
1179 if(!page) {
1180 tab = create_new_tab(widget, NULL);
1181 } else {
1182 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1183 }
1184
1185 GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
1186 gtk_dir_selection_hide_fileop_buttons(file_selector);
1187
1188 if(remember_trace_dir[0] != '\0')
1189 gtk_dir_selection_set_filename(file_selector, remember_trace_dir);
1190
1191 id = gtk_dialog_run(GTK_DIALOG(file_selector));
1192 switch(id){
1193 case GTK_RESPONSE_ACCEPT:
1194 case GTK_RESPONSE_OK:
1195 dir = gtk_dir_selection_get_dir (file_selector);
1196 strncpy(remember_trace_dir, dir, PATH_MAX);
1197 if(!dir || strlen(dir) == 0){
1198 gtk_widget_destroy((GtkWidget*)file_selector);
1199 break;
1200 }
1201 get_absolute_pathname(dir, abs_path);
1202 trace_v = lttvwindowtraces_get_trace_by_name(abs_path);
1203 if(trace_v == NULL) {
1204 trace = ltt_trace_open(abs_path);
1205 if(trace == NULL) {
1206 g_warning("cannot open trace %s", abs_path);
1207 } else {
1208 trace_v = lttv_trace_new(trace);
1209 lttvwindowtraces_add_trace(trace_v);
1210 lttvwindow_add_trace(tab, trace_v);
1211 }
1212 } else {
1213 lttvwindow_add_trace(tab, trace_v);
1214 }
1215
1216 gtk_widget_destroy((GtkWidget*)file_selector);
1217
1218 //update current tab
1219 //update_traceset(mw_data);
1220
1221 /* Call the updatetraceset hooks */
1222
1223 traceset = tab->traceset_info->traceset;
1224 SetTraceset(tab, traceset);
1225 // in expose now call_pending_read_hooks(mw_data);
1226
1227 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1228 break;
1229 case GTK_RESPONSE_REJECT:
1230 case GTK_RESPONSE_CANCEL:
1231 default:
1232 gtk_widget_destroy((GtkWidget*)file_selector);
1233 break;
1234 }
1235 }
1236
1237
1238 /* remove_trace_into_traceset_selector, each instance of a viewer has an associated
1239 * selector (filter), when a trace is remove from traceset, the selector should
1240 * reflect the change. The function is used to update the selector
1241 */
1242
1243 void remove_trace_from_traceset_selector(GtkMultiVPaned * paned, unsigned i)
1244 {
1245 LttvTracesetSelector * s;
1246 LttvTraceSelector * t;
1247 GtkWidget * w;
1248
1249 w = gtk_multi_vpaned_get_first_widget(paned);
1250 while(w){
1251 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1252 if(s){
1253 t = lttv_traceset_selector_trace_get(s,i);
1254 lttv_traceset_selector_trace_remove(s, i);
1255 lttv_trace_selector_destroy(t);
1256 }g_warning("Module dose not support filtering\n");
1257 w = gtk_multi_vpaned_get_next_widget(paned);
1258 }
1259 }
1260
1261
1262 /* remove_trace removes a trace from the current traceset if all viewers in
1263 * the current tab are not interested in the trace. It first displays a
1264 * dialogue, which shows all traces in the current traceset, to let user choose
1265 * a trace, then it checks if all viewers unselect the trace, if it is true,
1266 * it will remove the trace, recreate the traceset_contex,
1267 * and redraws all the viewer of the current tab. If there is on trace in the
1268 * current traceset, it will delete all viewers of the current tab
1269 */
1270
1271 void remove_trace(GtkWidget * widget, gpointer user_data)
1272 {
1273 LttTrace *trace;
1274 LttvTrace * trace_v;
1275 LttvTraceset * traceset;
1276 gint i, j, nb_trace;
1277 char ** name, *remove_trace_name;
1278 MainWindow * mw_data = get_window_data_struct(widget);
1279 LttvTracesetSelector * s;
1280 LttvTraceSelector * t;
1281 GtkWidget * w;
1282 gboolean selected;
1283 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1284
1285 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1286 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1287 Tab *tab;
1288
1289 if(!page) {
1290 return;
1291 } else {
1292 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1293 }
1294
1295 nb_trace =lttv_traceset_number(tab->traceset_info->traceset);
1296 name = g_new(char*,nb_trace);
1297 for(i = 0; i < nb_trace; i++){
1298 trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
1299 trace = lttv_trace(trace_v);
1300 name[i] = ltt_trace_name(trace);
1301 }
1302
1303 remove_trace_name = get_remove_trace(name, nb_trace);
1304
1305 if(remove_trace_name){
1306 for(i=0; i<nb_trace; i++){
1307 if(strcmp(remove_trace_name,name[i]) == 0){
1308 //unselect the trace from the current viewer
1309 w = gtk_multi_vpaned_get_widget(tab->multi_vpaned);
1310 if(w){
1311 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1312 if(s){
1313 t = lttv_traceset_selector_trace_get(s,i);
1314 lttv_trace_selector_set_selected(t, FALSE);
1315 }
1316
1317 //check if other viewers select the trace
1318 w = gtk_multi_vpaned_get_first_widget(tab->multi_vpaned);
1319 while(w){
1320 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1321 if(s){
1322 t = lttv_traceset_selector_trace_get(s,i);
1323 selected = lttv_trace_selector_get_selected(t);
1324 if(selected)break;
1325 }
1326 w = gtk_multi_vpaned_get_next_widget(tab->multi_vpaned);
1327 }
1328 }else selected = FALSE;
1329
1330 //if no viewer selects the trace, remove it
1331 if(!selected){
1332 remove_trace_from_traceset_selector(tab->multi_vpaned, i);
1333
1334 traceset = tab->traceset_info->traceset;
1335 //Keep a reference to the traces so they are not freed.
1336 for(j=0; j<lttv_traceset_number(traceset); j++)
1337 {
1338 LttvTrace * trace = lttv_traceset_get(traceset, j);
1339 lttv_trace_ref(trace);
1340 }
1341
1342 //remove state update hooks
1343 lttv_state_remove_event_hooks(
1344 (LttvTracesetState*)tab->traceset_info->traceset_context);
1345 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
1346 g_object_unref(tab->traceset_info->traceset_context);
1347
1348
1349 trace_v = lttv_traceset_get(traceset, i);
1350
1351 if(lttv_trace_get_ref_number(trace_v) <= 2) {
1352 /* ref 2 : traceset, local */
1353 lttvwindowtraces_remove_trace(trace_v);
1354 ltt_trace_close(lttv_trace(trace_v));
1355 }
1356
1357 lttv_traceset_remove(traceset, i);
1358 lttv_trace_unref(trace_v); // Remove local reference
1359
1360 if(!lttv_trace_get_ref_number(trace_v))
1361 lttv_trace_destroy(trace_v);
1362
1363 tab->traceset_info->traceset_context =
1364 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1365 lttv_context_init(
1366 LTTV_TRACESET_CONTEXT(tab->
1367 traceset_info->traceset_context),traceset);
1368 //add state update hooks
1369 lttv_state_add_event_hooks(
1370 (LttvTracesetState*)tab->traceset_info->traceset_context);
1371
1372 //Remove local reference to the traces.
1373 for(j=0; j<lttv_traceset_number(traceset); j++)
1374 {
1375 LttvTrace * trace = lttv_traceset_get(traceset, j);
1376 lttv_trace_unref(trace);
1377 }
1378
1379
1380 //update current tab
1381 //update_traceset(mw_data);
1382 if(nb_trace > 1){
1383
1384 SetTraceset(mw_data, (gpointer)traceset);
1385 // in expose now call_pending_read_hooks(mw_data);
1386
1387 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1388 }else{
1389 if(tab){
1390 while(tab->multi_vpaned->num_children){
1391 gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
1392 }
1393 }
1394 }
1395 }
1396 break;
1397 }
1398 }
1399 }
1400
1401 g_free(name);
1402 }
1403
1404
1405 /* Redraw all the viewers in the current tab */
1406 void redraw(GtkWidget *widget, gpointer user_data)
1407 {
1408 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1409 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1410 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1411 Tab *tab;
1412 if(!page) {
1413 return;
1414 } else {
1415 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1416 }
1417
1418 LttvHooks * tmp;
1419 LttvAttributeValue value;
1420
1421 g_assert(lttv_iattribute_find_by_path(tab->attributes, "hooks/redraw", LTTV_POINTER, &value));
1422
1423 tmp = (LttvHooks*)*(value.v_pointer);
1424 if(tmp != NULL)
1425 lttv_hooks_call(tmp,NULL);
1426 }
1427
1428
1429 void continue_processing(GtkWidget *widget, gpointer user_data)
1430 {
1431 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1432 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1433 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1434 Tab *tab;
1435 if(!page) {
1436 return;
1437 } else {
1438 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1439 }
1440
1441 LttvHooks * tmp;
1442 LttvAttributeValue value;
1443
1444 g_assert(lttv_iattribute_find_by_path(tab->attributes,
1445 "hooks/continue", LTTV_POINTER, &value));
1446
1447 tmp = (LttvHooks*)*(value.v_pointer);
1448 if(tmp != NULL)
1449 lttv_hooks_call(tmp,NULL);
1450 }
1451
1452 /* Stop the processing for the calling main window's current tab.
1453 * It removes every processing requests that are in its list. It does not call
1454 * the end request hooks, because the request is not finished.
1455 */
1456
1457 void stop_processing(GtkWidget *widget, gpointer user_data)
1458 {
1459 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1460 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1461 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1462 Tab *tab;
1463 if(!page) {
1464 return;
1465 } else {
1466 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1467 }
1468 GSList *events_requests = tab->events_requests;
1469
1470 GSList *iter = events_requests;
1471
1472 while(iter != NULL) {
1473 GSList *remove_iter = iter;
1474 iter = g_slist_next(iter);
1475
1476 g_free(remove_iter->data);
1477 events_requests = g_slist_remove_link(events_requests, remove_iter);
1478 }
1479 g_assert(g_slist_length(events_requests) == 0);
1480 }
1481
1482
1483 /* save will save the traceset to a file
1484 * Not implemented yet FIXME
1485 */
1486
1487 void save(GtkWidget * widget, gpointer user_data)
1488 {
1489 g_printf("Save\n");
1490 }
1491
1492 void save_as(GtkWidget * widget, gpointer user_data)
1493 {
1494 g_printf("Save as\n");
1495 }
1496
1497
1498 /* zoom will change the time_window of all the viewers of the
1499 * current tab, and redisplay them. The main functionality is to
1500 * determine the new time_window of the current tab
1501 */
1502
1503 void zoom(GtkWidget * widget, double size)
1504 {
1505 TimeInterval *time_span;
1506 TimeWindow new_time_window;
1507 LttTime current_time, time_delta, time_s, time_e, time_tmp;
1508 MainWindow * mw_data = get_window_data_struct(widget);
1509 LttvTracesetContext *tsc;
1510 GtkWidget * notebook = lookup_widget(widget, "MNotebook");
1511
1512 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1513 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1514 Tab *tab;
1515
1516 if(!page) {
1517 return;
1518 } else {
1519 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1520 }
1521
1522 if(size == 1) return;
1523
1524 tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
1525 time_span = &tsc->time_span;
1526 new_time_window = tab->time_window;
1527 current_time = tab->current_time;
1528
1529 time_delta = ltt_time_sub(time_span->end_time,time_span->start_time);
1530 if(size == 0){
1531 new_time_window.start_time = time_span->start_time;
1532 new_time_window.time_width = time_delta;
1533 }else{
1534 new_time_window.time_width = ltt_time_div(new_time_window.time_width, size);
1535 if(ltt_time_compare(new_time_window.time_width,time_delta) > 0)
1536 { /* Case where zoom out is bigger than trace length */
1537 new_time_window.start_time = time_span->start_time;
1538 new_time_window.time_width = time_delta;
1539 }
1540 else
1541 {
1542 /* Center the image on the current time */
1543 new_time_window.start_time =
1544 ltt_time_sub(current_time, ltt_time_div(new_time_window.time_width, 2.0));
1545 /* If on borders, don't fall off */
1546 if(ltt_time_compare(new_time_window.start_time, time_span->start_time) <0)
1547 {
1548 new_time_window.start_time = time_span->start_time;
1549 }
1550 else
1551 {
1552 if(ltt_time_compare(
1553 ltt_time_add(new_time_window.start_time, new_time_window.time_width),
1554 time_span->end_time) > 0)
1555 {
1556 new_time_window.start_time =
1557 ltt_time_sub(time_span->end_time, new_time_window.time_width);
1558 }
1559 }
1560
1561 }
1562
1563
1564
1565 //time_tmp = ltt_time_div(new_time_window.time_width, 2);
1566 //if(ltt_time_compare(current_time, time_tmp) < 0){
1567 // time_s = time_span->startTime;
1568 //} else {
1569 // time_s = ltt_time_sub(current_time,time_tmp);
1570 //}
1571 //time_e = ltt_time_add(current_time,time_tmp);
1572 //if(ltt_time_compare(time_span->startTime, time_s) > 0){
1573 // time_s = time_span->startTime;
1574 //}else if(ltt_time_compare(time_span->endTime, time_e) < 0){
1575 // time_e = time_span->endTime;
1576 // time_s = ltt_time_sub(time_e,new_time_window.time_width);
1577 //}
1578 //new_time_window.start_time = time_s;
1579 }
1580
1581 //lttvwindow_report_time_window(mw_data, &new_time_window);
1582 //call_pending_read_hooks(mw_data);
1583
1584 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1585 set_time_window(tab, &new_time_window);
1586 // in expose now call_pending_read_hooks(mw_data);
1587 gtk_multi_vpaned_set_adjust(tab->multi_vpaned, &new_time_window, FALSE);
1588 }
1589
1590 void zoom_in(GtkWidget * widget, gpointer user_data)
1591 {
1592 zoom(widget, 2);
1593 }
1594
1595 void zoom_out(GtkWidget * widget, gpointer user_data)
1596 {
1597 zoom(widget, 0.5);
1598 }
1599
1600 void zoom_extended(GtkWidget * widget, gpointer user_data)
1601 {
1602 zoom(widget, 0);
1603 }
1604
1605 void go_to_time(GtkWidget * widget, gpointer user_data)
1606 {
1607 g_printf("Go to time\n");
1608 }
1609
1610 void show_time_frame(GtkWidget * widget, gpointer user_data)
1611 {
1612 g_printf("Show time frame\n");
1613 }
1614
1615
1616 /* callback function */
1617
1618 void
1619 on_empty_traceset_activate (GtkMenuItem *menuitem,
1620 gpointer user_data)
1621 {
1622 create_new_window((GtkWidget*)menuitem, user_data, FALSE);
1623 }
1624
1625
1626 void
1627 on_clone_traceset_activate (GtkMenuItem *menuitem,
1628 gpointer user_data)
1629 {
1630 create_new_window((GtkWidget*)menuitem, user_data, TRUE);
1631 }
1632
1633
1634 /* create_new_tab calls create_tab to construct a new tab in the main window
1635 */
1636
1637 Tab *create_new_tab(GtkWidget* widget, gpointer user_data){
1638 gchar label[PATH_MAX];
1639 MainWindow * mw_data = get_window_data_struct(widget);
1640
1641 GtkNotebook * notebook = (GtkNotebook *)lookup_widget(widget, "MNotebook");
1642 if(notebook == NULL){
1643 g_printf("Notebook does not exist\n");
1644 return NULL;
1645 }
1646 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1647 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1648 Tab *copy_tab;
1649
1650 if(!page) {
1651 copy_tab = NULL;
1652 } else {
1653 copy_tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1654 }
1655
1656 strcpy(label,"Page");
1657 if(get_label(mw_data, label,"Get the name of the tab","Please input tab's name"))
1658 return (create_tab (mw_data, copy_tab, notebook, label));
1659 }
1660
1661 void
1662 on_tab_activate (GtkMenuItem *menuitem,
1663 gpointer user_data)
1664 {
1665 create_new_tab((GtkWidget*)menuitem, user_data);
1666 }
1667
1668
1669 void
1670 on_open_activate (GtkMenuItem *menuitem,
1671 gpointer user_data)
1672 {
1673 open_traceset((GtkWidget*)menuitem, user_data);
1674 }
1675
1676
1677 void
1678 on_close_activate (GtkMenuItem *menuitem,
1679 gpointer user_data)
1680 {
1681 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
1682 main_window_destructor(mw_data);
1683 }
1684
1685
1686 /* remove the current tab from the main window
1687 */
1688
1689 void
1690 on_close_tab_activate (GtkWidget *widget,
1691 gpointer user_data)
1692 {
1693 gint page_num;
1694 GtkWidget * notebook;
1695 GtkWidget * page;
1696 MainWindow * mw_data = get_window_data_struct(widget);
1697 notebook = lookup_widget(widget, "MNotebook");
1698 if(notebook == NULL){
1699 g_printf("Notebook does not exist\n");
1700 return;
1701 }
1702
1703 page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
1704
1705 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
1706
1707 }
1708
1709 void
1710 on_close_tab_X_clicked (GtkWidget *widget,
1711 gpointer user_data)
1712 {
1713 gint page_num;
1714 GtkWidget *notebook = lookup_widget(widget, "MNotebook");
1715 if(notebook == NULL){
1716 g_printf("Notebook does not exist\n");
1717 return;
1718 }
1719
1720 if((page_num = gtk_notebook_page_num(GTK_NOTEBOOK(notebook), widget)) != -1)
1721 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
1722
1723 }
1724
1725
1726 void
1727 on_add_trace_activate (GtkMenuItem *menuitem,
1728 gpointer user_data)
1729 {
1730 add_trace((GtkWidget*)menuitem, user_data);
1731 }
1732
1733
1734 void
1735 on_remove_trace_activate (GtkMenuItem *menuitem,
1736 gpointer user_data)
1737 {
1738 remove_trace((GtkWidget*)menuitem, user_data);
1739 }
1740
1741
1742 void
1743 on_save_activate (GtkMenuItem *menuitem,
1744 gpointer user_data)
1745 {
1746 save((GtkWidget*)menuitem, user_data);
1747 }
1748
1749
1750 void
1751 on_save_as_activate (GtkMenuItem *menuitem,
1752 gpointer user_data)
1753 {
1754 save_as((GtkWidget*)menuitem, user_data);
1755 }
1756
1757
1758 void
1759 on_quit_activate (GtkMenuItem *menuitem,
1760 gpointer user_data)
1761 {
1762 gtk_main_quit ();
1763 }
1764
1765
1766 void
1767 on_cut_activate (GtkMenuItem *menuitem,
1768 gpointer user_data)
1769 {
1770 g_printf("Cut\n");
1771 }
1772
1773
1774 void
1775 on_copy_activate (GtkMenuItem *menuitem,
1776 gpointer user_data)
1777 {
1778 g_printf("Copye\n");
1779 }
1780
1781
1782 void
1783 on_paste_activate (GtkMenuItem *menuitem,
1784 gpointer user_data)
1785 {
1786 g_printf("Paste\n");
1787 }
1788
1789
1790 void
1791 on_delete_activate (GtkMenuItem *menuitem,
1792 gpointer user_data)
1793 {
1794 g_printf("Delete\n");
1795 }
1796
1797
1798 void
1799 on_zoom_in_activate (GtkMenuItem *menuitem,
1800 gpointer user_data)
1801 {
1802 zoom_in((GtkWidget*)menuitem, user_data);
1803 }
1804
1805
1806 void
1807 on_zoom_out_activate (GtkMenuItem *menuitem,
1808 gpointer user_data)
1809 {
1810 zoom_out((GtkWidget*)menuitem, user_data);
1811 }
1812
1813
1814 void
1815 on_zoom_extended_activate (GtkMenuItem *menuitem,
1816 gpointer user_data)
1817 {
1818 zoom_extended((GtkWidget*)menuitem, user_data);
1819 }
1820
1821
1822 void
1823 on_go_to_time_activate (GtkMenuItem *menuitem,
1824 gpointer user_data)
1825 {
1826 go_to_time((GtkWidget*)menuitem, user_data);
1827 }
1828
1829
1830 void
1831 on_show_time_frame_activate (GtkMenuItem *menuitem,
1832 gpointer user_data)
1833 {
1834 show_time_frame((GtkWidget*)menuitem, user_data);
1835 }
1836
1837
1838 void
1839 on_move_viewer_up_activate (GtkMenuItem *menuitem,
1840 gpointer user_data)
1841 {
1842 move_up_viewer((GtkWidget*)menuitem, user_data);
1843 }
1844
1845
1846 void
1847 on_move_viewer_down_activate (GtkMenuItem *menuitem,
1848 gpointer user_data)
1849 {
1850 move_down_viewer((GtkWidget*)menuitem, user_data);
1851 }
1852
1853
1854 void
1855 on_remove_viewer_activate (GtkMenuItem *menuitem,
1856 gpointer user_data)
1857 {
1858 delete_viewer((GtkWidget*)menuitem, user_data);
1859 }
1860
1861 void
1862 on_trace_filter_activate (GtkMenuItem *menuitem,
1863 gpointer user_data)
1864 {
1865 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
1866 LttvTracesetSelector * s;
1867 GtkWidget * w;
1868 GtkWidget * notebook = lookup_widget(GTK_WIDGET(menuitem), "MNotebook");
1869
1870 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
1871 gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
1872 Tab *tab;
1873
1874 if(!page) {
1875 return;
1876 } else {
1877 tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
1878 }
1879
1880 w = gtk_multi_vpaned_get_widget(tab->multi_vpaned);
1881
1882 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1883 if(!s){
1884 g_printf("There is no viewer yet\n");
1885 return;
1886 }
1887 if(get_filter_selection(s, "Configure trace and tracefile filter", "Select traces and tracefiles")){
1888 //FIXME report filter change
1889 //update_traceset(mw_data);
1890 //call_pending_read_hooks(mw_data);
1891 //lttvwindow_report_current_time(mw_data,&(tab->current_time));
1892 }
1893 }
1894
1895 void
1896 on_trace_facility_activate (GtkMenuItem *menuitem,
1897 gpointer user_data)
1898 {
1899 g_printf("Trace facility selector: %s\n");
1900 }
1901
1902
1903 /* Dispaly a file selection dialogue to let user select a module, then call
1904 * lttv_module_load(), finally insert tool button and menu entry in the main window
1905 * for the loaded module
1906 */
1907
1908 void
1909 on_load_module_activate (GtkMenuItem *menuitem,
1910 gpointer user_data)
1911 {
1912 char ** dir;
1913 gint id;
1914 char str[PATH_MAX], *str1;
1915 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
1916 GtkFileSelection * file_selector = (GtkFileSelection *)gtk_file_selection_new("Select a module");
1917 if(remember_plugins_dir[0] != '\0')
1918 gtk_file_selection_set_filename(file_selector, remember_plugins_dir);
1919 gtk_file_selection_hide_fileop_buttons(file_selector);
1920
1921 str[0] = '\0';
1922 id = gtk_dialog_run(GTK_DIALOG(file_selector));
1923 switch(id){
1924 case GTK_RESPONSE_ACCEPT:
1925 case GTK_RESPONSE_OK:
1926 dir = gtk_file_selection_get_selections (file_selector);
1927 strncpy(str,dir[0],PATH_MAX);
1928 strncpy(remember_plugins_dir,dir[0],PATH_MAX);
1929 str1 = strrchr(str,'/');
1930 if(str1)str1++;
1931 else{
1932 str1 = strrchr(str,'\\');
1933 str1++;
1934 }
1935 lttv_module_require(str1, NULL);
1936 g_strfreev(dir);
1937 case GTK_RESPONSE_REJECT:
1938 case GTK_RESPONSE_CANCEL:
1939 default:
1940 gtk_widget_destroy((GtkWidget*)file_selector);
1941 break;
1942 }
1943 g_printf("Load module: %s\n", str);
1944 }
1945
1946
1947 /* Display all loaded modules, let user to select a module to unload
1948 * by calling lttv_module_unload
1949 */
1950
1951 void
1952 on_unload_module_activate (GtkMenuItem *menuitem,
1953 gpointer user_data)
1954 {
1955 int i;
1956 GPtrArray *name;
1957 char *unload_module_name;
1958 guint nb;
1959 LttvLibrary *library;
1960 LttvLibraryInfo library_info;
1961 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
1962
1963 name = g_ptr_array_new();
1964 nb = lttv_library_number();
1965
1966 for(i=0;i<nb;i++){
1967 library = lttv_library_get(i);
1968 lttv_library_info(library, &library_info);
1969 if(library_info.load_count > 0) g_ptr_array_add(name, library_info.name);
1970 }
1971
1972 unload_module_name =get_unload_module((char **)(name->pdata), name->len);
1973
1974 if(unload_module_name){
1975 for(i=0;i<nb;i++){
1976 library = lttv_library_get(i);
1977 lttv_library_info(library, &library_info);
1978 if(strcmp(unload_module_name, library_info.name) == 0){
1979 lttv_library_unload(library);
1980 break;
1981 }
1982 }
1983 }
1984
1985 g_ptr_array_free(name, TRUE);
1986 }
1987
1988
1989 /* Display a directory dialogue to let user select a path for module searching
1990 */
1991
1992 void
1993 on_add_module_search_path_activate (GtkMenuItem *menuitem,
1994 gpointer user_data)
1995 {
1996 GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select module path");
1997 const char * dir;
1998 gint id;
1999
2000 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2001 if(remember_plugins_dir[0] != '\0')
2002 gtk_dir_selection_set_filename(file_selector, remember_plugins_dir);
2003
2004 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2005 switch(id){
2006 case GTK_RESPONSE_ACCEPT:
2007 case GTK_RESPONSE_OK:
2008 dir = gtk_dir_selection_get_dir (file_selector);
2009 strncpy(remember_plugins_dir,dir,PATH_MAX);
2010 strncat(remember_plugins_dir,"/",PATH_MAX);
2011 lttv_library_path_add(dir);
2012 case GTK_RESPONSE_REJECT:
2013 case GTK_RESPONSE_CANCEL:
2014 default:
2015 gtk_widget_destroy((GtkWidget*)file_selector);
2016 break;
2017 }
2018 }
2019
2020
2021 void
2022 on_color_activate (GtkMenuItem *menuitem,
2023 gpointer user_data)
2024 {
2025 g_printf("Color\n");
2026 }
2027
2028
2029 void
2030 on_filter_activate (GtkMenuItem *menuitem,
2031 gpointer user_data)
2032 {
2033 g_printf("Filter\n");
2034 }
2035
2036
2037 void
2038 on_save_configuration_activate (GtkMenuItem *menuitem,
2039 gpointer user_data)
2040 {
2041 g_printf("Save configuration\n");
2042 }
2043
2044
2045 void
2046 on_content_activate (GtkMenuItem *menuitem,
2047 gpointer user_data)
2048 {
2049 g_printf("Content\n");
2050 }
2051
2052
2053 void
2054 on_about_activate (GtkMenuItem *menuitem,
2055 gpointer user_data)
2056 {
2057 g_printf("About...\n");
2058 }
2059
2060
2061 void
2062 on_button_new_clicked (GtkButton *button,
2063 gpointer user_data)
2064 {
2065 create_new_window((GtkWidget*)button, user_data, TRUE);
2066 }
2067
2068 void
2069 on_button_new_tab_clicked (GtkButton *button,
2070 gpointer user_data)
2071 {
2072 create_new_tab((GtkWidget*)button, user_data);
2073 }
2074
2075 void
2076 on_button_open_clicked (GtkButton *button,
2077 gpointer user_data)
2078 {
2079 open_traceset((GtkWidget*)button, user_data);
2080 }
2081
2082
2083 void
2084 on_button_add_trace_clicked (GtkButton *button,
2085 gpointer user_data)
2086 {
2087 add_trace((GtkWidget*)button, user_data);
2088 }
2089
2090
2091 void
2092 on_button_remove_trace_clicked (GtkButton *button,
2093 gpointer user_data)
2094 {
2095 remove_trace((GtkWidget*)button, user_data);
2096 }
2097
2098 void
2099 on_button_redraw_clicked (GtkButton *button,
2100 gpointer user_data)
2101 {
2102 redraw((GtkWidget*)button, user_data);
2103 }
2104
2105 void
2106 on_button_continue_processing_clicked (GtkButton *button,
2107 gpointer user_data)
2108 {
2109 continue_processing((GtkWidget*)button, user_data);
2110 }
2111
2112 void
2113 on_button_stop_processing_clicked (GtkButton *button,
2114 gpointer user_data)
2115 {
2116 stop_processing((GtkWidget*)button, user_data);
2117 }
2118
2119
2120
2121 void
2122 on_button_save_clicked (GtkButton *button,
2123 gpointer user_data)
2124 {
2125 save((GtkWidget*)button, user_data);
2126 }
2127
2128
2129 void
2130 on_button_save_as_clicked (GtkButton *button,
2131 gpointer user_data)
2132 {
2133 save_as((GtkWidget*)button, user_data);
2134 }
2135
2136
2137 void
2138 on_button_zoom_in_clicked (GtkButton *button,
2139 gpointer user_data)
2140 {
2141 zoom_in((GtkWidget*)button, user_data);
2142 }
2143
2144
2145 void
2146 on_button_zoom_out_clicked (GtkButton *button,
2147 gpointer user_data)
2148 {
2149 zoom_out((GtkWidget*)button, user_data);
2150 }
2151
2152
2153 void
2154 on_button_zoom_extended_clicked (GtkButton *button,
2155 gpointer user_data)
2156 {
2157 zoom_extended((GtkWidget*)button, user_data);
2158 }
2159
2160
2161 void
2162 on_button_go_to_time_clicked (GtkButton *button,
2163 gpointer user_data)
2164 {
2165 go_to_time((GtkWidget*)button, user_data);
2166 }
2167
2168
2169 void
2170 on_button_show_time_frame_clicked (GtkButton *button,
2171 gpointer user_data)
2172 {
2173 show_time_frame((GtkWidget*)button, user_data);
2174 }
2175
2176
2177 void
2178 on_button_move_up_clicked (GtkButton *button,
2179 gpointer user_data)
2180 {
2181 move_up_viewer((GtkWidget*)button, user_data);
2182 }
2183
2184
2185 void
2186 on_button_move_down_clicked (GtkButton *button,
2187 gpointer user_data)
2188 {
2189 move_down_viewer((GtkWidget*)button, user_data);
2190 }
2191
2192
2193 void
2194 on_button_delete_viewer_clicked (GtkButton *button,
2195 gpointer user_data)
2196 {
2197 delete_viewer((GtkWidget*)button, user_data);
2198 }
2199
2200 void
2201 on_MWindow_destroy (GtkWidget *widget,
2202 gpointer user_data)
2203 {
2204 MainWindow *main_window = get_window_data_struct(widget);
2205 LttvIAttribute *attributes = main_window->attributes;
2206 LttvAttributeValue value;
2207
2208 //This is unnecessary, since widgets will be destroyed
2209 //by the main window widget anyway.
2210 //remove_all_menu_toolbar_constructors(main_window, NULL);
2211
2212 g_assert(lttv_iattribute_find_by_path(attributes,
2213 "viewers/menu", LTTV_POINTER, &value));
2214 lttv_menus_destroy((LttvMenus*)*(value.v_pointer));
2215
2216 g_assert(lttv_iattribute_find_by_path(attributes,
2217 "viewers/toolbar", LTTV_POINTER, &value));
2218 lttv_toolbars_destroy((LttvToolbars*)*(value.v_pointer));
2219
2220 g_object_unref(main_window->attributes);
2221 g_main_window_list = g_slist_remove(g_main_window_list, main_window);
2222
2223 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list));
2224 if(g_slist_length(g_main_window_list) == 0)
2225 gtk_main_quit ();
2226 }
2227
2228 gboolean
2229 on_MWindow_configure (GtkWidget *widget,
2230 GdkEventConfigure *event,
2231 gpointer user_data)
2232 {
2233 MainWindow * mw_data = get_window_data_struct((GtkWidget*)widget);
2234 float width = event->width;
2235 TimeWindow time_win;
2236 double ratio;
2237 TimeInterval *time_span;
2238 LttTime time;
2239
2240 // MD : removed time width modification upon resizing of the main window.
2241 // The viewers will redraw themselves completely, without time interval
2242 // modification.
2243 /* while(tab){
2244 if(mw_data->window_width){
2245 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
2246 time_win = tab->time_window;
2247 ratio = width / mw_data->window_width;
2248 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
2249 time = ltt_time_sub(time_span->endTime, time_win.start_time);
2250 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
2251 tab->time_window.time_width = time;
2252 }
2253 }
2254 tab = tab->next;
2255 }
2256
2257 mw_data->window_width = (int)width;
2258 */
2259 return FALSE;
2260 }
2261
2262 /* Set current tab
2263 */
2264
2265 void
2266 on_MNotebook_switch_page (GtkNotebook *notebook,
2267 GtkNotebookPage *page,
2268 guint page_num,
2269 gpointer user_data)
2270 {
2271
2272 }
2273
2274
2275 /* callback function to check or uncheck the check box (filter)
2276 */
2277
2278 void checkbox_changed(GtkTreeView *treeview,
2279 GtkTreePath *arg1,
2280 GtkTreeViewColumn *arg2,
2281 gpointer user_data)
2282 {
2283 GtkTreeStore * store = (GtkTreeStore *)gtk_tree_view_get_model (treeview);
2284 GtkTreeIter iter;
2285 gboolean value;
2286
2287 if (gtk_tree_model_get_iter ((GtkTreeModel *)store, &iter, arg1)){
2288 gtk_tree_model_get ((GtkTreeModel *)store, &iter, CHECKBOX_COLUMN, &value, -1);
2289 value = value? FALSE : TRUE;
2290 gtk_tree_store_set (GTK_TREE_STORE (store), &iter, CHECKBOX_COLUMN, value, -1);
2291 }
2292
2293 }
2294
2295
2296 /* According to user's selection, update selector(filter)
2297 */
2298
2299 void update_filter(LttvTracesetSelector *s, GtkTreeStore *store )
2300 {
2301 GtkTreeIter iter, child_iter, child_iter1, child_iter2;
2302 int i, j, k, nb_eventtype;
2303 LttvTraceSelector * trace;
2304 LttvTracefileSelector * tracefile;
2305 LttvEventtypeSelector * eventtype;
2306 gboolean value, value1, value2;
2307
2308 if(gtk_tree_model_get_iter_first((GtkTreeModel*)store, &iter)){
2309 i = 0;
2310 do{
2311 trace = lttv_traceset_selector_trace_get(s, i);
2312 nb_eventtype = lttv_trace_selector_eventtype_number(trace);
2313 gtk_tree_model_get ((GtkTreeModel*)store, &iter, CHECKBOX_COLUMN, &value,-1);
2314 if(value){
2315 j = 0;
2316 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter, &iter)){
2317 do{
2318 if(j<1){//eventtype selector for trace
2319 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter, CHECKBOX_COLUMN, &value2,-1);
2320 if(value2){
2321 k=0;
2322 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter1, &child_iter)){
2323 do{
2324 eventtype = lttv_trace_selector_eventtype_get(trace,k);
2325 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter1, CHECKBOX_COLUMN, &value2,-1);
2326 lttv_eventtype_selector_set_selected(eventtype,value2);
2327 k++;
2328 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter1));
2329 }
2330 }
2331 }else{ //tracefile selector
2332 tracefile = lttv_trace_selector_tracefile_get(trace, j - 1);
2333 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter, CHECKBOX_COLUMN, &value1,-1);
2334 lttv_tracefile_selector_set_selected(tracefile,value1);
2335 if(value1){
2336 gtk_tree_model_iter_children((GtkTreeModel*)store, &child_iter1, &child_iter); //eventtype selector
2337 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter1, CHECKBOX_COLUMN, &value2,-1);
2338 if(value2){
2339 k = 0;
2340 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter2, &child_iter1)){
2341 do{//eventtype selector for tracefile
2342 eventtype = lttv_tracefile_selector_eventtype_get(tracefile,k);
2343 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter2, CHECKBOX_COLUMN, &value2,-1);
2344 lttv_eventtype_selector_set_selected(eventtype,value2);
2345 k++;
2346 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter2));
2347 }
2348 }
2349 }
2350 }
2351 j++;
2352 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter));
2353 }
2354 }
2355 lttv_trace_selector_set_selected(trace,value);
2356 i++;
2357 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &iter));
2358 }
2359 }
2360
2361
2362 /* Display a dialogue showing all eventtypes and traces, let user to select the interested
2363 * eventtypes, tracefiles and traces (filter)
2364 */
2365
2366 gboolean get_filter_selection(LttvTracesetSelector *s,char *title, char * column_title)
2367 {
2368 GtkWidget * dialogue;
2369 GtkTreeStore * store;
2370 GtkWidget * tree;
2371 GtkWidget * scroll_win;
2372 GtkCellRenderer * renderer;
2373 GtkTreeViewColumn * column;
2374 GtkTreeIter iter, child_iter, child_iter1, child_iter2;
2375 int i, j, k, id, nb_trace, nb_tracefile, nb_eventtype;
2376 LttvTraceSelector * trace;
2377 LttvTracefileSelector * tracefile;
2378 LttvEventtypeSelector * eventtype;
2379 char * name;
2380 gboolean checked;
2381
2382 dialogue = gtk_dialog_new_with_buttons(title,
2383 NULL,
2384 GTK_DIALOG_MODAL,
2385 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
2386 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
2387 NULL);
2388 gtk_window_set_default_size((GtkWindow*)dialogue, 300, 500);
2389
2390 store = gtk_tree_store_new (TOTAL_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING);
2391 tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
2392 g_object_unref (G_OBJECT (store));
2393 g_signal_connect (G_OBJECT (tree), "row-activated",
2394 G_CALLBACK (checkbox_changed),
2395 NULL);
2396
2397
2398 renderer = gtk_cell_renderer_toggle_new ();
2399 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle *)renderer, FALSE);
2400
2401 g_object_set (G_OBJECT (renderer),"activatable", TRUE, NULL);
2402
2403 column = gtk_tree_view_column_new_with_attributes ("Checkbox",
2404 renderer,
2405 "active", CHECKBOX_COLUMN,
2406 NULL);
2407 gtk_tree_view_column_set_alignment (column, 0.5);
2408 gtk_tree_view_column_set_fixed_width (column, 20);
2409 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
2410
2411 renderer = gtk_cell_renderer_text_new ();
2412 column = gtk_tree_view_column_new_with_attributes (column_title,
2413 renderer,
2414 "text", NAME_COLUMN,
2415 NULL);
2416 gtk_tree_view_column_set_alignment (column, 0.0);
2417 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
2418 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree), FALSE);
2419
2420 scroll_win = gtk_scrolled_window_new (NULL, NULL);
2421 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
2422 GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
2423 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
2424
2425 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
2426
2427 gtk_widget_show(scroll_win);
2428 gtk_widget_show(tree);
2429
2430 nb_trace = lttv_traceset_selector_trace_number(s);
2431 for(i=0;i<nb_trace;i++){
2432 trace = lttv_traceset_selector_trace_get(s, i);
2433 name = lttv_trace_selector_get_name(trace);
2434 gtk_tree_store_append (store, &iter, NULL);
2435 checked = lttv_trace_selector_get_selected(trace);
2436 gtk_tree_store_set (store, &iter,
2437 CHECKBOX_COLUMN,checked,
2438 NAME_COLUMN,name,
2439 -1);
2440
2441 gtk_tree_store_append (store, &child_iter, &iter);
2442 gtk_tree_store_set (store, &child_iter,
2443 CHECKBOX_COLUMN, checked,
2444 NAME_COLUMN,"eventtype",
2445 -1);
2446
2447 nb_eventtype = lttv_trace_selector_eventtype_number(trace);
2448 for(j=0;j<nb_eventtype;j++){
2449 eventtype = lttv_trace_selector_eventtype_get(trace,j);
2450 name = lttv_eventtype_selector_get_name(eventtype);
2451 checked = lttv_eventtype_selector_get_selected(eventtype);
2452 gtk_tree_store_append (store, &child_iter1, &child_iter);
2453 gtk_tree_store_set (store, &child_iter1,
2454 CHECKBOX_COLUMN, checked,
2455 NAME_COLUMN,name,
2456 -1);
2457 }
2458
2459 nb_tracefile = lttv_trace_selector_tracefile_number(trace);
2460 for(j=0;j<nb_tracefile;j++){
2461 tracefile = lttv_trace_selector_tracefile_get(trace, j);
2462 name = lttv_tracefile_selector_get_name(tracefile);
2463 gtk_tree_store_append (store, &child_iter, &iter);
2464 checked = lttv_tracefile_selector_get_selected(tracefile);
2465 gtk_tree_store_set (store, &child_iter,
2466 CHECKBOX_COLUMN, checked,
2467 NAME_COLUMN,name,
2468 -1);
2469
2470 gtk_tree_store_append (store, &child_iter1, &child_iter);
2471 gtk_tree_store_set (store, &child_iter1,
2472 CHECKBOX_COLUMN, checked,
2473 NAME_COLUMN,"eventtype",
2474 -1);
2475
2476 for(k=0;k<nb_eventtype;k++){
2477 eventtype = lttv_tracefile_selector_eventtype_get(tracefile,k);
2478 name = lttv_eventtype_selector_get_name(eventtype);
2479 checked = lttv_eventtype_selector_get_selected(eventtype);
2480 gtk_tree_store_append (store, &child_iter2, &child_iter1);
2481 gtk_tree_store_set (store, &child_iter2,
2482 CHECKBOX_COLUMN, checked,
2483 NAME_COLUMN,name,
2484 -1);
2485 }
2486 }
2487 }
2488
2489 id = gtk_dialog_run(GTK_DIALOG(dialogue));
2490 switch(id){
2491 case GTK_RESPONSE_ACCEPT:
2492 case GTK_RESPONSE_OK:
2493 update_filter(s, store);
2494 gtk_widget_destroy(dialogue);
2495 return TRUE;
2496 case GTK_RESPONSE_REJECT:
2497 case GTK_RESPONSE_CANCEL:
2498 default:
2499 gtk_widget_destroy(dialogue);
2500 break;
2501 }
2502 return FALSE;
2503 }
2504
2505
2506 /* Select a trace which will be removed from traceset
2507 */
2508
2509 char * get_remove_trace(char ** all_trace_name, int nb_trace)
2510 {
2511 return get_selection(all_trace_name, nb_trace,
2512 "Select a trace", "Trace pathname");
2513 }
2514
2515
2516 /* Select a module which will be unloaded
2517 */
2518
2519 char * get_unload_module(char ** loaded_module_name, int nb_module)
2520 {
2521 return get_selection(loaded_module_name, nb_module,
2522 "Select an unload module", "Module pathname");
2523 }
2524
2525
2526 /* Display a dialogue which shows all selectable items, let user to
2527 * select one of them
2528 */
2529
2530 char * get_selection(char ** loaded_module_name, int nb_module,
2531 char *title, char * column_title)
2532 {
2533 GtkWidget * dialogue;
2534 GtkWidget * scroll_win;
2535 GtkWidget * tree;
2536 GtkListStore * store;
2537 GtkTreeViewColumn * column;
2538 GtkCellRenderer * renderer;
2539 GtkTreeSelection * select;
2540 GtkTreeIter iter;
2541 gint id, i;
2542 char * unload_module_name = NULL;
2543
2544 dialogue = gtk_dialog_new_with_buttons(title,
2545 NULL,
2546 GTK_DIALOG_MODAL,
2547 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
2548 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
2549 NULL);
2550 gtk_window_set_default_size((GtkWindow*)dialogue, 500, 200);
2551
2552 scroll_win = gtk_scrolled_window_new (NULL, NULL);
2553 gtk_widget_show ( scroll_win);
2554 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
2555 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2556
2557 store = gtk_list_store_new (N_COLUMNS,G_TYPE_STRING);
2558 tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL (store));
2559 gtk_widget_show ( tree);
2560 g_object_unref (G_OBJECT (store));
2561
2562 renderer = gtk_cell_renderer_text_new ();
2563 column = gtk_tree_view_column_new_with_attributes (column_title,
2564 renderer,
2565 "text", MODULE_COLUMN,
2566 NULL);
2567 gtk_tree_view_column_set_alignment (column, 0.5);
2568 gtk_tree_view_column_set_fixed_width (column, 150);
2569 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
2570
2571 select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
2572 gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
2573
2574 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
2575
2576 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
2577
2578 for(i=0;i<nb_module;i++){
2579 gtk_list_store_append (store, &iter);
2580 gtk_list_store_set (store, &iter, MODULE_COLUMN,loaded_module_name[i],-1);
2581 }
2582
2583 id = gtk_dialog_run(GTK_DIALOG(dialogue));
2584 switch(id){
2585 case GTK_RESPONSE_ACCEPT:
2586 case GTK_RESPONSE_OK:
2587 if (gtk_tree_selection_get_selected (select, (GtkTreeModel**)&store, &iter)){
2588 gtk_tree_model_get ((GtkTreeModel*)store, &iter, MODULE_COLUMN, &unload_module_name, -1);
2589 }
2590 case GTK_RESPONSE_REJECT:
2591 case GTK_RESPONSE_CANCEL:
2592 default:
2593 gtk_widget_destroy(dialogue);
2594 break;
2595 }
2596
2597 return unload_module_name;
2598 }
2599
2600
2601 /* Insert all menu entry and tool buttons into this main window
2602 * for modules.
2603 *
2604 */
2605
2606 void add_all_menu_toolbar_constructors(MainWindow * mw, gpointer user_data)
2607 {
2608 int i;
2609 GdkPixbuf *pixbuf;
2610 lttvwindow_viewer_constructor constructor;
2611 LttvMenus * global_menu, * instance_menu;
2612 LttvToolbars * global_toolbar, * instance_toolbar;
2613 LttvMenuClosure *menu_item;
2614 LttvToolbarClosure *toolbar_item;
2615 LttvAttributeValue value;
2616 LttvIAttribute *global_attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
2617 LttvIAttribute *attributes = mw->attributes;
2618 GtkWidget * tool_menu_title_menu, *new_widget, *pixmap;
2619
2620 g_assert(lttv_iattribute_find_by_path(global_attributes,
2621 "viewers/menu", LTTV_POINTER, &value));
2622 if(*(value.v_pointer) == NULL)
2623 *(value.v_pointer) = lttv_menus_new();
2624 global_menu = (LttvMenus*)*(value.v_pointer);
2625
2626 g_assert(lttv_iattribute_find_by_path(attributes,
2627 "viewers/menu", LTTV_POINTER, &value));
2628 if(*(value.v_pointer) == NULL)
2629 *(value.v_pointer) = lttv_menus_new();
2630 instance_menu = (LttvMenus*)*(value.v_pointer);
2631
2632
2633
2634 g_assert(lttv_iattribute_find_by_path(global_attributes,
2635 "viewers/toolbar", LTTV_POINTER, &value));
2636 if(*(value.v_pointer) == NULL)
2637 *(value.v_pointer) = lttv_toolbars_new();
2638 global_toolbar = (LttvToolbars*)*(value.v_pointer);
2639
2640 g_assert(lttv_iattribute_find_by_path(attributes,
2641 "viewers/toolbar", LTTV_POINTER, &value));
2642 if(*(value.v_pointer) == NULL)
2643 *(value.v_pointer) = lttv_toolbars_new();
2644 instance_toolbar = (LttvToolbars*)*(value.v_pointer);
2645
2646 /* Add missing menu entries to window instance */
2647 for(i=0;i<global_menu->len;i++) {
2648 menu_item = &g_array_index(global_menu, LttvMenuClosure, i);
2649
2650 //add menu_item to window instance;
2651 constructor = menu_item->con;
2652 tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
2653 new_widget =
2654 gtk_menu_item_new_with_mnemonic (menu_item->menu_text);
2655 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu),
2656 new_widget);
2657 g_signal_connect ((gpointer) new_widget, "activate",
2658 G_CALLBACK (insert_viewer_wrap),
2659 constructor);
2660 gtk_widget_show (new_widget);
2661 lttv_menus_add(instance_menu, menu_item->con,
2662 menu_item->menu_path,
2663 menu_item->menu_text,
2664 new_widget);
2665
2666 }
2667
2668 /* Add missing toolbar entries to window instance */
2669 for(i=0;i<global_toolbar->len;i++) {
2670 toolbar_item = &g_array_index(global_toolbar, LttvToolbarClosure, i);
2671
2672 //add toolbar_item to window instance;
2673 constructor = toolbar_item->con;
2674 tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1");
2675 pixbuf = gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item->pixmap);
2676 pixmap = gtk_image_new_from_pixbuf(pixbuf);
2677 new_widget =
2678 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu),
2679 GTK_TOOLBAR_CHILD_BUTTON,
2680 NULL,
2681 "",
2682 toolbar_item->tooltip, NULL,
2683 pixmap, NULL, NULL);
2684 gtk_label_set_use_underline(
2685 GTK_LABEL (((GtkToolbarChild*) (
2686 g_list_last (GTK_TOOLBAR
2687 (tool_menu_title_menu)->children)->data))->label),
2688 TRUE);
2689 gtk_container_set_border_width (GTK_CONTAINER (new_widget), 1);
2690 g_signal_connect ((gpointer) new_widget,
2691 "clicked",
2692 G_CALLBACK (insert_viewer_wrap),
2693 constructor);
2694 gtk_widget_show (new_widget);
2695
2696 lttv_toolbars_add(instance_toolbar, toolbar_item->con,
2697 toolbar_item->tooltip,
2698 toolbar_item->pixmap,
2699 new_widget);
2700
2701 }
2702
2703 }
2704
2705
2706 /* Create a main window
2707 */
2708
2709 void construct_main_window(MainWindow * parent)
2710 {
2711 g_debug("construct_main_window()");
2712 GtkWidget * new_window; /* New generated main window */
2713 MainWindow * new_m_window;/* New main window structure */
2714 GtkNotebook * notebook;
2715 LttvIAttribute *attributes =
2716 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
2717 LttvAttributeValue value;
2718 Tab *new_tab;
2719
2720 new_m_window = g_new(MainWindow, 1);
2721
2722 // Add the object's information to the module's array
2723 g_main_window_list = g_slist_append(g_main_window_list, new_m_window);
2724
2725
2726 new_window = create_MWindow();
2727 gtk_widget_show (new_window);
2728
2729 new_m_window->mwindow = new_window;
2730 new_m_window->attributes = attributes;
2731
2732 g_assert(lttv_iattribute_find_by_path(attributes,
2733 "viewers/menu", LTTV_POINTER, &value));
2734 *(value.v_pointer) = lttv_menus_new();
2735
2736 g_assert(lttv_iattribute_find_by_path(attributes,
2737 "viewers/toolbar", LTTV_POINTER, &value));
2738 *(value.v_pointer) = lttv_toolbars_new();
2739
2740 add_all_menu_toolbar_constructors(new_m_window, NULL);
2741
2742 g_object_set_data_full(G_OBJECT(new_window),
2743 "main_window_data",
2744 (gpointer)new_m_window,
2745 (GDestroyNotify)g_free);
2746 //create a default tab
2747 notebook = (GtkNotebook *)lookup_widget(new_m_window->mwindow, "MNotebook");
2748 if(notebook == NULL){
2749 g_printf("Notebook does not exist\n");
2750 return;
2751 }
2752 gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
2753 //for now there is no name field in LttvTraceset structure
2754 //Use "Traceset" as the label for the default tab
2755 if(parent) {
2756 GtkWidget * parent_notebook = lookup_widget(parent->mwindow, "MNotebook");
2757 GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook),
2758 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook)));
2759 Tab *parent_tab;
2760
2761 if(!page) {
2762 parent_tab = NULL;
2763 } else {
2764 parent_tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
2765 }
2766 new_tab = create_tab(new_m_window, parent_tab, notebook, "Traceset");
2767 } else {
2768 new_tab = create_tab(new_m_window, NULL, notebook, "Traceset");
2769 if(g_init_trace != NULL){
2770 lttvwindow_add_trace(new_tab,
2771 g_init_trace);
2772 }
2773 }
2774
2775 g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list));
2776 }
2777
2778
2779 /* Free the memory occupied by a tab structure
2780 * destroy the tab
2781 */
2782
2783 void tab_destructor(Tab * tab_instance)
2784 {
2785 int i, nb, ref_count;
2786 LttvTrace * trace;
2787
2788 if(tab_instance->attributes)
2789 g_object_unref(tab_instance->attributes);
2790
2791 if(tab_instance->interrupted_state)
2792 g_object_unref(tab_instance->interrupted_state);
2793
2794
2795 if(tab_instance->traceset_info->traceset_context != NULL){
2796 //remove state update hooks
2797 lttv_state_remove_event_hooks(
2798 (LttvTracesetState*)tab_instance->traceset_info->
2799 traceset_context);
2800 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab_instance->traceset_info->
2801 traceset_context));
2802 g_object_unref(tab_instance->traceset_info->traceset_context);
2803 }
2804 if(tab_instance->traceset_info->traceset != NULL) {
2805 nb = lttv_traceset_number(tab_instance->traceset_info->traceset);
2806 for(i = 0 ; i < nb ; i++) {
2807 trace = lttv_traceset_get(tab_instance->traceset_info->traceset, i);
2808 ref_count = lttv_trace_get_ref_number(trace);
2809 if(ref_count <= 1){
2810 ltt_trace_close(lttv_trace(trace));
2811 }
2812 }
2813 }
2814 lttv_traceset_destroy(tab_instance->traceset_info->traceset);
2815 /* Remove the idle events requests processing function of the tab */
2816 g_idle_remove_by_data(tab_instance);
2817
2818 g_slist_free(tab_instance->events_requests);
2819 g_free(tab_instance->traceset_info);
2820 g_free(tab_instance);
2821 }
2822
2823
2824 /* Create a tab and insert it into the current main window
2825 */
2826
2827 Tab* create_tab(MainWindow * mw, Tab *copy_tab,
2828 GtkNotebook * notebook, char * label)
2829 {
2830 GList * list;
2831 Tab * tab;
2832 LttTime tmp_time;
2833
2834 //create a new tab data structure
2835 tab = g_new(Tab,1);
2836
2837 //construct and initialize the traceset_info
2838 tab->traceset_info = g_new(TracesetInfo,1);
2839
2840 if(copy_tab) {
2841 tab->traceset_info->traceset =
2842 lttv_traceset_copy(copy_tab->traceset_info->traceset);
2843 } else {
2844 tab->traceset_info->traceset = lttv_traceset_new();
2845 }
2846
2847 //FIXME : this is g_debug level
2848 lttv_attribute_write_xml(
2849 lttv_traceset_attribute(tab->traceset_info->traceset),
2850 stdout,
2851 0, 4);
2852 fflush(stdout);
2853
2854
2855 //FIXME copy not implemented in lower level
2856 tab->traceset_info->traceset_context =
2857 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
2858 g_assert(tab->traceset_info->traceset_context != NULL);
2859 lttv_context_init(
2860 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context),
2861 tab->traceset_info->traceset);
2862 //add state update hooks
2863 lttv_state_add_event_hooks(
2864 (LttvTracesetState*)tab->traceset_info->traceset_context);
2865
2866 //determine the current_time and time_window of the tab
2867 if(copy_tab != NULL){
2868 tab->time_window = copy_tab->time_window;
2869 tab->current_time = copy_tab->current_time;
2870 }else{
2871 tab->time_window.start_time =
2872 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
2873 time_span.start_time;
2874 if(DEFAULT_TIME_WIDTH_S <
2875 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
2876 time_span.end_time.tv_sec)
2877 tmp_time.tv_sec = DEFAULT_TIME_WIDTH_S;
2878 else
2879 tmp_time.tv_sec =
2880 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
2881 time_span.end_time.tv_sec;
2882 tmp_time.tv_nsec = 0;
2883 tab->time_window.time_width = tmp_time ;
2884 tab->current_time.tv_sec =
2885 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
2886 time_span.start_time.tv_sec;
2887 tab->current_time.tv_nsec =
2888 LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
2889 time_span.start_time.tv_nsec;
2890 }
2891 tab->attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
2892 tab->interrupted_state = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
2893 tab->multi_vpaned = (GtkMultiVPaned*)gtk_multi_vpaned_new();
2894 gtk_widget_show((GtkWidget*)tab->multi_vpaned);
2895 tab->mw = mw;
2896
2897 /*{
2898 // Display a label with a X
2899 GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
2900 GtkWidget *w_label = gtk_label_new (label);
2901 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
2902 GtkWidget *w_button = gtk_button_new ();
2903 gtk_container_add(GTK_CONTAINER(w_button), pixmap);
2904 //GtkWidget *w_button = gtk_button_new_with_label("x");
2905
2906 gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
2907
2908 gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
2909 gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
2910 FALSE, 0);
2911
2912 g_signal_connect_swapped (w_button, "clicked",
2913 G_CALLBACK (on_close_tab_X_clicked),
2914 tab->multi_vpaned);
2915
2916 gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
2917
2918 gtk_widget_show (w_label);
2919 gtk_widget_show (pixmap);
2920 gtk_widget_show (w_button);
2921 gtk_widget_show (w_hbox);
2922
2923 tab->label = w_hbox;
2924 }*/
2925
2926
2927 tab->label = gtk_label_new (label);
2928 gtk_widget_show (tab->label);
2929
2930
2931 /* Start with empty events requests list */
2932 tab->events_requests = NULL;
2933 tab->events_request_pending = FALSE;
2934
2935 g_object_set_data_full(
2936 G_OBJECT(tab->multi_vpaned),
2937 "Tab_Info",
2938 tab,
2939 (GDestroyNotify)tab_destructor);
2940
2941 //insert tab into notebook
2942 gtk_notebook_append_page(notebook,
2943 (GtkWidget*)tab->multi_vpaned,
2944 tab->label);
2945 list = gtk_container_get_children(GTK_CONTAINER(notebook));
2946 gtk_notebook_set_current_page(notebook,g_list_length(list)-1);
2947 // always show : not if(g_list_length(list)>1)
2948 gtk_notebook_set_show_tabs(notebook, TRUE);
2949
2950 return tab;
2951 }
2952
2953 /*
2954 * execute_events_requests
2955 *
2956 * Idle function that executes the pending requests for a tab.
2957 *
2958 * @return return value : TRUE : keep the idle function, FALSE : remove it.
2959 */
2960 gboolean execute_events_requests(Tab *tab)
2961 {
2962 return ( lttvwindow_process_pending_requests(tab) );
2963 }
2964
This page took 0.096889 seconds and 5 git commands to generate.