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