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