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