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