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