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