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