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