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