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