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