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