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