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