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