FIXME for pending request
[lttv.git] / ltt / branches / poly / lttv / modules / gui / lttvwindow / lttvwindow / callbacks.c
CommitLineData
e076699e 1/* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 XangXiu Yang
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
16 * MA 02111-1307, USA.
17 */
18
561eba2a 19#ifdef HAVE_CONFIG_H
20# include <config.h>
21#endif
22
23#include <gtk/gtk.h>
561eba2a 24
25#include "callbacks.h"
26#include "interface.h"
27#include "support.h"
a43d67ba 28#include <ltt/trace.h>
29#include <ltt/facility.h>
30#include <ltt/time.h>
31#include <ltt/event.h>
2a2fa4f0 32#include <lttv/lttv.h>
a43d67ba 33#include <lttv/module.h>
34#include <lttv/iattribute.h>
35#include <lttv/stats.h>
13f86ce2 36#include <lttvwindow/mainwindow.h>
37#include <lttvwindow/menu.h>
38#include <lttvwindow/toolbar.h>
36b40c74 39#include <lttvwindow/viewer.h>
13f86ce2 40#include <lttvwindow/gtkdirsel.h>
13f86ce2 41#include <lttvwindow/lttvfilter.h>
6b1d3120 42
f7afe191 43#define PATH_LENGTH 256
44#define DEFAULT_TIME_WIDTH_S 1
45
49bf71b5 46extern LttvTrace *g_init_trace ;
561eba2a 47
ec25ff5e 48
49/** Array containing instanced objects. */
68b48a45 50extern GSList * g_main_window_list;
561eba2a 51
68b48a45 52static int g_win_count = 0;
7a859036 53
a43d67ba 54/** MD : keep old directory. */
3658a338 55static char remember_plugins_dir[PATH_LENGTH] = "";
56static char remember_trace_dir[PATH_LENGTH] = "";
6fbb1ddf 57
58
bca3b81f 59MainWindow * get_window_data_struct(GtkWidget * widget);
36b3c068 60char * get_unload_module(char ** loaded_module_name, int nb_module);
2176f952 61char * get_remove_trace(char ** all_trace_name, int nb_trace);
62char * get_selection(char ** all_name, int nb, char *title, char * column_title);
a8c0f09d 63gboolean get_filter_selection(LttvTracesetSelector *s, char *title, char * column_title);
716e4367 64void * create_tab(MainWindow * parent, MainWindow * current_window,
65 GtkNotebook * notebook, char * label);
561eba2a 66
42fcbb71 67void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor);
49bf71b5 68void update_filter(LttvTracesetSelector *s, GtkTreeStore *store );
69
70void checkbox_changed(GtkTreeView *treeview,
71 GtkTreePath *arg1,
72 GtkTreeViewColumn *arg2,
73 gpointer user_data);
74void remove_trace_from_traceset_selector(GtkMultiVPaned * paned, unsigned i);
75void add_trace_into_traceset_selector(GtkMultiVPaned * paned, LttTrace * trace);
76
77LttvTracesetSelector * construct_traceset_selector(LttvTraceset * traceset);
78
a43d67ba 79void call_pending_read_hooks(MainWindow * mw_data);
a8c0f09d 80unsigned get_max_event_number(MainWindow * mw_data);
202f6c8f 81
49bf71b5 82enum {
83 CHECKBOX_COLUMN,
84 NAME_COLUMN,
85 TOTAL_COLUMNS
86};
561eba2a 87
36b3c068 88enum
89{
90 MODULE_COLUMN,
91 N_COLUMNS
92};
93
abe346a3 94/* Construct a selector(filter), which will be associated with a viewer,
95 * and provides an interface for user to select interested events and traces
96 */
561eba2a 97
49bf71b5 98LttvTracesetSelector * construct_traceset_selector(LttvTraceset * traceset)
99{
100 LttvTracesetSelector * s;
101 LttvTraceSelector * trace;
102 LttvTracefileSelector * tracefile;
ed3b99b6 103 LttvEventtypeSelector * eventtype;
104 int i, j, k, m;
105 int nb_trace, nb_tracefile, nb_control, nb_per_cpu, nb_facility, nb_event;
49bf71b5 106 LttvTrace * trace_v;
107 LttTrace * t;
108 LttTracefile *tf;
ed3b99b6 109 LttFacility * fac;
110 LttEventType * et;
49bf71b5 111
112 s = lttv_traceset_selector_new(lttv_traceset_name(traceset));
113 nb_trace = lttv_traceset_number(traceset);
114 for(i=0;i<nb_trace;i++){
115 trace_v = lttv_traceset_get(traceset, i);
116 t = lttv_trace(trace_v);
117 trace = lttv_trace_selector_new(t);
ed3b99b6 118 lttv_traceset_selector_trace_add(s, trace);
119
120 nb_facility = ltt_trace_facility_number(t);
121 for(k=0;k<nb_facility;k++){
122 fac = ltt_trace_facility_get(t,k);
123 nb_event = (int) ltt_facility_eventtype_number(fac);
124 for(m=0;m<nb_event;m++){
125 et = ltt_facility_eventtype_get(fac,m);
126 eventtype = lttv_eventtype_selector_new(et);
127 lttv_trace_selector_eventtype_add(trace, eventtype);
128 }
129 }
130
49bf71b5 131 nb_control = ltt_trace_control_tracefile_number(t);
132 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(t);
133 nb_tracefile = nb_control + nb_per_cpu;
134
135 for(j = 0 ; j < nb_tracefile ; j++) {
136 if(j < nb_control)
137 tf = ltt_trace_control_tracefile_get(t, j);
138 else
139 tf = ltt_trace_per_cpu_tracefile_get(t, j - nb_control);
140 tracefile = lttv_tracefile_selector_new(tf);
ed3b99b6 141 lttv_trace_selector_tracefile_add(trace, tracefile);
142 lttv_eventtype_selector_copy(trace, tracefile);
49bf71b5 143 }
144 }
145 return s;
146}
147
abe346a3 148
149/* insert_viewer function constructs an instance of a viewer first,
150 * then inserts the widget of the instance into the container of the
151 * main window
152 */
153
561eba2a 154void
606309a4 155insert_viewer_wrap(GtkWidget *menuitem, gpointer user_data)
561eba2a 156{
157 guint val = 20;
606309a4 158
42fcbb71 159 insert_viewer((GtkWidget*)menuitem, (lttvwindow_viewer_constructor)user_data);
37d0eca6 160 // selected_hook(&val);
561eba2a 161}
162
561eba2a 163
164/* internal functions */
42fcbb71 165void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor)
561eba2a 166{
daecc161 167 GtkMultiVPaned * multi_vpaned;
bca3b81f 168 MainWindow * mw_data;
f9334f6f 169 GtkWidget * viewer;
49bf71b5 170 LttvTracesetSelector * s;
202f6c8f 171 TimeInterval * time_interval;
561eba2a 172
68b48a45 173 mw_data = get_window_data_struct(widget);
bca3b81f 174 if(!mw_data->current_tab) return;
daecc161 175 multi_vpaned = mw_data->current_tab->multi_vpaned;
561eba2a 176
49bf71b5 177 s = construct_traceset_selector(mw_data->current_tab->traceset_info->traceset);
178 viewer = (GtkWidget*)constructor(mw_data, s, "Traceset_Selector");
f9334f6f 179 if(viewer)
f0d936c0 180 {
daecc161 181 gtk_multi_vpaned_widget_add(multi_vpaned, viewer);
a43d67ba 182 // We unref here, because it is now referenced by the multi_vpaned!
183 g_object_unref(G_OBJECT(viewer));
184
185 // The viewer will show itself when it receives a show notify
186 // So we call the show notify hooks here. It will
187 // typically add hooks for reading, we call process trace, and the
188 // end of reading hook will call gtk_widget_show and unregister the
189 // hooks.
190 // Note that show notify gets the time_requested through the call_data.
191 //show_viewer(mw_data);
192 // in expose now call_pending_read_hooks(mw_data);
f0d936c0 193 }
561eba2a 194}
195
abe346a3 196
197/* get_label function is used to get user input, it displays an input
198 * box, which allows user to input a string
199 */
200
561eba2a 201void get_label_string (GtkWidget * text, gchar * label)
202{
203 GtkEntry * entry = (GtkEntry*)text;
204 if(strlen(gtk_entry_get_text(entry))!=0)
205 strcpy(label,gtk_entry_get_text(entry));
206}
207
eb38aea5 208gboolean get_label(MainWindow * mw, gchar * str, gchar* dialogue_title, gchar * label_str)
561eba2a 209{
210 GtkWidget * dialogue;
211 GtkWidget * text;
212 GtkWidget * label;
213 gint id;
214
5723fa24 215 dialogue = gtk_dialog_new_with_buttons(dialogue_title,NULL,
561eba2a 216 GTK_DIALOG_MODAL,
217 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
218 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
219 NULL);
220
6b1d3120 221 label = gtk_label_new(label_str);
561eba2a 222 gtk_widget_show(label);
223
224 text = gtk_entry_new();
225 gtk_widget_show(text);
226
227 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), label,TRUE, TRUE,0);
228 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), text,FALSE, FALSE,0);
229
230 id = gtk_dialog_run(GTK_DIALOG(dialogue));
231 switch(id){
232 case GTK_RESPONSE_ACCEPT:
233 get_label_string(text,str);
234 gtk_widget_destroy(dialogue);
235 break;
236 case GTK_RESPONSE_REJECT:
237 default:
238 gtk_widget_destroy(dialogue);
eb38aea5 239 return FALSE;
561eba2a 240 }
eb38aea5 241 return TRUE;
561eba2a 242}
243
abe346a3 244
245/* get_window_data_struct function is actually a lookup function,
246 * given a widget which is in the tree of the main window, it will
247 * return the MainWindow data structure associated with main window
248 */
249
bca3b81f 250MainWindow * get_window_data_struct(GtkWidget * widget)
561eba2a 251{
252 GtkWidget * mw;
bca3b81f 253 MainWindow * mw_data;
561eba2a 254
255 mw = lookup_widget(widget, "MWindow");
256 if(mw == NULL){
257 g_printf("Main window does not exist\n");
258 return;
259 }
260
bca3b81f 261 mw_data = (MainWindow *) g_object_get_data(G_OBJECT(mw),"mainWindow");
68b48a45 262 if(mw_data == NULL){
561eba2a 263 g_printf("Main window data does not exist\n");
264 return;
265 }
68b48a45 266 return mw_data;
561eba2a 267}
268
abe346a3 269
270/* create_new_window function, just constructs a new main window
271 */
272
68b48a45 273void create_new_window(GtkWidget* widget, gpointer user_data, gboolean clone)
561eba2a 274{
bca3b81f 275 MainWindow * parent = get_window_data_struct(widget);
561eba2a 276
561eba2a 277 if(clone){
278 g_printf("Clone : use the same traceset\n");
08b1c66e 279 construct_main_window(parent);
561eba2a 280 }else{
281 g_printf("Empty : traceset is set to NULL\n");
08b1c66e 282 construct_main_window(NULL);
561eba2a 283 }
284}
285
abe346a3 286
287/* move_*_viewer functions move the selected view up/down in
288 * the current tab
289 */
290
561eba2a 291void move_up_viewer(GtkWidget * widget, gpointer user_data)
292{
bca3b81f 293 MainWindow * mw = get_window_data_struct(widget);
294 if(!mw->current_tab) return;
daecc161 295 gtk_multi_vpaned_widget_move_up(mw->current_tab->multi_vpaned);
561eba2a 296}
297
298void move_down_viewer(GtkWidget * widget, gpointer user_data)
299{
bca3b81f 300 MainWindow * mw = get_window_data_struct(widget);
301 if(!mw->current_tab) return;
daecc161 302 gtk_multi_vpaned_widget_move_down(mw->current_tab->multi_vpaned);
561eba2a 303}
304
abe346a3 305
306/* delete_viewer deletes the selected viewer in the current tab
307 */
308
561eba2a 309void delete_viewer(GtkWidget * widget, gpointer user_data)
310{
bca3b81f 311 MainWindow * mw = get_window_data_struct(widget);
312 if(!mw->current_tab) return;
daecc161 313 gtk_multi_vpaned_widget_delete(mw->current_tab->multi_vpaned);
561eba2a 314}
315
abe346a3 316
317/* open_traceset will open a traceset saved in a file
318 * Right now, it is not finished yet, (not working)
a43d67ba 319 * FIXME
abe346a3 320 */
321
561eba2a 322void open_traceset(GtkWidget * widget, gpointer user_data)
323{
2176f952 324 char ** dir;
325 gint id;
326 LttvTraceset * traceset;
bca3b81f 327 MainWindow * mw_data = get_window_data_struct(widget);
68b48a45 328 GtkFileSelection * file_selector =
2176f952 329 (GtkFileSelection *)gtk_file_selection_new("Select a traceset");
330
68b48a45 331 gtk_file_selection_hide_fileop_buttons(file_selector);
c64c7ea1 332
68b48a45 333 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2176f952 334 switch(id){
335 case GTK_RESPONSE_ACCEPT:
336 case GTK_RESPONSE_OK:
68b48a45 337 dir = gtk_file_selection_get_selections (file_selector);
2176f952 338 traceset = lttv_traceset_load(dir[0]);
339 g_printf("Open a trace set %s\n", dir[0]);
340 //Not finished yet
341 g_strfreev(dir);
342 case GTK_RESPONSE_REJECT:
343 case GTK_RESPONSE_CANCEL:
344 default:
68b48a45 345 gtk_widget_destroy((GtkWidget*)file_selector);
2176f952 346 break;
347 }
c64c7ea1 348
561eba2a 349}
350
abe346a3 351
352/* get_max_event_number returns the event number limit used by
353 * lttv_process_traceset(LttvTracesetContext, endTime, maxNumEvents)
354 * each viewer can set the limit
355 */
356
a8c0f09d 357unsigned get_max_event_number(MainWindow * mw_data)
202f6c8f 358{
a8c0f09d 359 unsigned nb = 0, *size;
360 GtkWidget * w;
361
362 w = gtk_multi_vpaned_get_first_widget(mw_data->current_tab->multi_vpaned);
363 while(w){
364 size = (unsigned*)g_object_get_data(G_OBJECT(w), MAX_NUMBER_EVENT);
365 if(size == NULL){
366 nb = G_MAXULONG;
367 break;
368 }else{
369 if(nb < *size)
370 nb = *size;
371 }
372 w = gtk_multi_vpaned_get_next_widget(mw_data->current_tab->multi_vpaned);
373 }
374 return nb;
375}
376
abe346a3 377
a43d67ba 378/* call_pending_read_hooks parses the traceset first by calling
491f466f 379 * process_traceset, then display all viewers of
abe346a3 380 * the current tab
a43d67ba 381 * It will then remove all entries from the time_requests array.
abe346a3 382 */
383
a43d67ba 384gint compare_time_request(TimeRequest *a, TimeRequest *b)
385{
386 return ltt_time_compare(a->time_window.start_time, b->time_window.start_time);
387}
388
389void call_pending_read_hooks(MainWindow * mw_data)
a8c0f09d 390{
391 unsigned max_nb_events;
392 GdkWindow * win;
393 GdkCursor * new;
394 GtkWidget* widget;
a43d67ba 395 int i;
396 LttvTracesetContext *tsc;
397
398 /* Current tab check : if no current tab is present, no hooks to call. */
399 /* It makes the expose works.. */
400 if(mw_data->current_tab == NULL)
401 return;
402
403 if(mw_data->current_tab->time_requests->len == 0)
404 return;
405
406 LttvHooks *tmp_hooks = lttv_hooks_new();
407
408 tsc =
224446ce 409 LTTV_TRACESET_CONTEXT(mw_data->current_tab->traceset_info->
491f466f 410 traceset_context);
a8c0f09d 411
abe346a3 412 //set the cursor to be X shape, indicating that the computer is busy in doing its job
a8c0f09d 413 new = gdk_cursor_new(GDK_X_CURSOR);
efde9138 414 widget = lookup_widget(mw_data->mwindow, "MToolbar1");
a8c0f09d 415 win = gtk_widget_get_parent_window(widget);
416 gdk_window_set_cursor(win, new);
417 gdk_cursor_unref(new);
418 gdk_window_stick(win);
419 gdk_window_unstick(win);
a43d67ba 420
421
422 g_array_sort(mw_data->current_tab->time_requests,
423 (GCompareFunc)compare_time_request);
424
425
202f6c8f 426 //update time window of each viewer, let viewer insert hooks needed by process_traceset
a43d67ba 427 //lttvwindow_report_time_window(mw_data, time_window);
a8c0f09d 428
a43d67ba 429 //max_nb_events = get_max_event_number(mw_data);
202f6c8f 430
431 //call hooks to show each viewer and let them remove hooks
a43d67ba 432 //show_viewer(mw_data);
a8c0f09d 433
a43d67ba 434 // FIXME
435 // call process trace for each time interval
436 // Will have to be combined!
437 g_critical("SIZE time req len : %d", mw_data->current_tab->time_requests->len);
438
439 //g_assert(mw_data->current_tab->time_requests->len <= 1); //FIXME
440 /* Go through each time request. As they are already sorted by start_time,
441 * we check with the current event time if processing is needed. */
442 for(i=0; i < mw_data->current_tab->time_requests->len; i++)
443 {
444 g_critical("RUN i %d", i);
445 TimeRequest *time_request =
446 &g_array_index(mw_data->current_tab->time_requests, TimeRequest, i);
447 LttTime end_time = ltt_time_add( time_request->time_window.start_time,
448 time_request->time_window.time_width);
449
05a85b91 450 if(i == 0 || !(ltt_time_compare(time_request->time_window.start_time, ltt_event_time(tsc->e))<0) )//FIXME This comparison makes no sense (the author) :)
a43d67ba 451 {
452 /* do it if first request or start_time >= last event's time */
453 lttv_process_traceset_seek_time(tsc, time_request->time_window.start_time);
454 lttv_process_traceset(tsc, end_time, time_request->num_events);
455 }
456
457 /* Call the end of process_traceset hook */
458 lttv_hooks_add(tmp_hooks,
459 time_request->after_hook,
460 time_request->after_hook_data);
461 lttv_hooks_call(tmp_hooks, time_request);
462 lttv_hooks_remove(tmp_hooks, time_request->after_hook);
463 }
464
465 /* Free the time requests */
466 g_array_free(mw_data->current_tab->time_requests, TRUE);
467 mw_data->current_tab->time_requests =
468 g_array_new(FALSE, FALSE, sizeof(TimeRequest));
469
470 mw_data->current_tab->time_request_pending = FALSE;
471
472 lttv_hooks_destroy(tmp_hooks);
473
abe346a3 474 //set the cursor back to normal
a8c0f09d 475 gdk_window_set_cursor(win, NULL);
202f6c8f 476}
477
abe346a3 478
479/* add_trace_into_traceset_selector, each instance of a viewer has an associated
480 * selector (filter), when a trace is added into traceset, the selector should
481 * reflect the change. The function is used to update the selector
482 */
483
49bf71b5 484void add_trace_into_traceset_selector(GtkMultiVPaned * paned, LttTrace * t)
485{
ed3b99b6 486 int j, k, m, nb_tracefile, nb_control, nb_per_cpu, nb_facility, nb_event;
49bf71b5 487 LttvTracesetSelector * s;
488 LttvTraceSelector * trace;
489 LttvTracefileSelector * tracefile;
ed3b99b6 490 LttvEventtypeSelector * eventtype;
49bf71b5 491 LttTracefile * tf;
492 GtkWidget * w;
ed3b99b6 493 LttFacility * fac;
494 LttEventType * et;
49bf71b5 495
496 w = gtk_multi_vpaned_get_first_widget(paned);
497 while(w){
498 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
49bf71b5 499
abe346a3 500 if(s){
501 trace = lttv_trace_selector_new(t);
502 lttv_traceset_selector_trace_add(s, trace);
503
504 nb_facility = ltt_trace_facility_number(t);
505 for(k=0;k<nb_facility;k++){
506 fac = ltt_trace_facility_get(t,k);
507 nb_event = (int) ltt_facility_eventtype_number(fac);
508 for(m=0;m<nb_event;m++){
509 et = ltt_facility_eventtype_get(fac,m);
510 eventtype = lttv_eventtype_selector_new(et);
511 lttv_trace_selector_eventtype_add(trace, eventtype);
512 }
513 }
514
515 nb_control = ltt_trace_control_tracefile_number(t);
516 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(t);
517 nb_tracefile = nb_control + nb_per_cpu;
518
519 for(j = 0 ; j < nb_tracefile ; j++) {
520 if(j < nb_control)
521 tf = ltt_trace_control_tracefile_get(t, j);
522 else
523 tf = ltt_trace_per_cpu_tracefile_get(t, j - nb_control);
524 tracefile = lttv_tracefile_selector_new(tf);
525 lttv_trace_selector_tracefile_add(trace, tracefile);
526 lttv_eventtype_selector_copy(trace, tracefile);
527 }
528 }else g_warning("Module does not support filtering\n");
49bf71b5 529
530 w = gtk_multi_vpaned_get_next_widget(paned);
531 }
532}
533
abe346a3 534
535/* add_trace adds a trace into the current traceset. It first displays a
536 * directory selection dialogue to let user choose a trace, then recreates
537 * tracset_context, and redraws all the viewer of the current tab
538 */
539
561eba2a 540void add_trace(GtkWidget * widget, gpointer user_data)
541{
2176f952 542 LttTrace *trace;
543 LttvTrace * trace_v;
544 LttvTraceset * traceset;
94dcfb9e 545 const char * dir;
2176f952 546 gint id;
a43d67ba 547 gint i;
bca3b81f 548 MainWindow * mw_data = get_window_data_struct(widget);
68b48a45 549 GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
550 gtk_dir_selection_hide_fileop_buttons(file_selector);
3658a338 551 if(remember_trace_dir[0] != '\0')
552 gtk_dir_selection_set_filename(file_selector, remember_trace_dir);
2176f952 553
68b48a45 554 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2176f952 555 switch(id){
556 case GTK_RESPONSE_ACCEPT:
557 case GTK_RESPONSE_OK:
68b48a45 558 dir = gtk_dir_selection_get_dir (file_selector);
3658a338 559 strncpy(remember_trace_dir, dir, PATH_LENGTH);
a43d67ba 560 if(!dir || strlen(dir) == 0){
561 gtk_widget_destroy((GtkWidget*)file_selector);
562 break;
284675e3 563 }
2176f952 564 trace = ltt_trace_open(dir);
565 if(trace == NULL) g_critical("cannot open trace %s", dir);
566 trace_v = lttv_trace_new(trace);
716e4367 567 traceset = mw_data->current_tab->traceset_info->traceset;
c2619a30 568
a43d67ba 569 //Keep a reference to the traces so they are not freed.
570 for(i=0; i<lttv_traceset_number(traceset); i++)
571 {
572 LttvTrace * trace = lttv_traceset_get(traceset, i);
573 lttv_trace_ref(trace);
574 }
575
576 //remove state update hooks
577 lttv_state_remove_event_hooks(
578 (LttvTracesetState*)mw_data->current_tab->traceset_info->traceset_context);
579
580 lttv_context_fini(LTTV_TRACESET_CONTEXT(
581 mw_data->current_tab->traceset_info->traceset_context));
582 g_object_unref(mw_data->current_tab->traceset_info->traceset_context);
583
c2619a30 584
2176f952 585 lttv_traceset_add(traceset, trace_v);
a43d67ba 586
587 /* Create new context */
716e4367 588 mw_data->current_tab->traceset_info->traceset_context =
c2619a30 589 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
2176f952 590 lttv_context_init(
c2619a30 591 LTTV_TRACESET_CONTEXT(mw_data->current_tab->traceset_info->
592 traceset_context),
593 traceset);
784705cc 594 //add state update hooks
595 lttv_state_add_event_hooks(
596 (LttvTracesetState*)mw_data->current_tab->traceset_info->traceset_context);
a43d67ba 597 //Remove local reference to the traces.
598 for(i=0; i<lttv_traceset_number(traceset); i++)
c2619a30 599 {
a43d67ba 600 LttvTrace * trace = lttv_traceset_get(traceset, i);
601 lttv_trace_unref(trace);
c2619a30 602 }
603
604
49bf71b5 605 add_trace_into_traceset_selector(mw_data->current_tab->multi_vpaned, trace);
606
607 gtk_widget_destroy((GtkWidget*)file_selector);
608
609 //update current tab
a43d67ba 610 //update_traceset(mw_data);
21e8c385 611
297f7a48 612 //get_traceset_time_span(mw_data,LTTV_TRACESET_CONTEXT(mw_data->current_tab->traceset_info->traceset_context)->Time_Span);
a43d67ba 613 if(
614 lttv_traceset_number(mw_data->current_tab->traceset_info->traceset) == 1
615 || ltt_time_compare(mw_data->current_tab->current_time,
616 LTTV_TRACESET_CONTEXT(mw_data->current_tab->traceset_info->
617 traceset_context)->Time_Span->startTime)<0)
618 {
619 /* Set initial time if this is the first trace in the traceset */
620 mw_data->current_tab->current_time =
621 LTTV_TRACESET_CONTEXT(mw_data->current_tab->traceset_info->
622 traceset_context)->Time_Span->startTime;
623 mw_data->current_tab->time_window.start_time =
624 mw_data->current_tab->current_time;
625 mw_data->current_tab->time_window.time_width.tv_sec =
626 DEFAULT_TIME_WIDTH_S;
627 mw_data->current_tab->time_window.time_width.tv_nsec = 0;
21e8c385 628 }
629
a43d67ba 630 /* Call the updatetraceset hooks */
631
632 SetTraceset(mw_data, (gpointer)traceset);
633 // in expose now call_pending_read_hooks(mw_data);
634
635 //lttvwindow_report_current_time(mw_data,&(mw_data->current_tab->current_time));
49bf71b5 636 break;
2176f952 637 case GTK_RESPONSE_REJECT:
638 case GTK_RESPONSE_CANCEL:
639 default:
68b48a45 640 gtk_widget_destroy((GtkWidget*)file_selector);
2176f952 641 break;
642 }
49bf71b5 643}
644
abe346a3 645
646/* remove_trace_into_traceset_selector, each instance of a viewer has an associated
647 * selector (filter), when a trace is remove from traceset, the selector should
648 * reflect the change. The function is used to update the selector
649 */
650
49bf71b5 651void remove_trace_from_traceset_selector(GtkMultiVPaned * paned, unsigned i)
652{
653 LttvTracesetSelector * s;
654 LttvTraceSelector * t;
655 GtkWidget * w;
656
657 w = gtk_multi_vpaned_get_first_widget(paned);
658 while(w){
659 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
abe346a3 660 if(s){
661 t = lttv_traceset_selector_trace_get(s,i);
662 lttv_traceset_selector_trace_remove(s, i);
663 lttv_trace_selector_destroy(t);
664 }g_warning("Module dose not support filtering\n");
49bf71b5 665 w = gtk_multi_vpaned_get_next_widget(paned);
666 }
561eba2a 667}
668
abe346a3 669
670/* remove_trace removes a trace from the current traceset if all viewers in
671 * the current tab are not interested in the trace. It first displays a
672 * dialogue, which shows all traces in the current traceset, to let user choose
673 * a trace, then it checks if all viewers unselect the trace, if it is true,
674 * it will remove the trace, recreate the traceset_contex,
675 * and redraws all the viewer of the current tab. If there is on trace in the
676 * current traceset, it will delete all viewers of the current tab
677 */
678
561eba2a 679void remove_trace(GtkWidget * widget, gpointer user_data)
680{
2176f952 681 LttTrace *trace;
682 LttvTrace * trace_v;
683 LttvTraceset * traceset;
a43d67ba 684 gint i, j, nb_trace;
2176f952 685 char ** name, *remove_trace_name;
bca3b81f 686 MainWindow * mw_data = get_window_data_struct(widget);
49bf71b5 687 LttvTracesetSelector * s;
688 LttvTraceSelector * t;
689 GtkWidget * w;
690 gboolean selected;
2176f952 691
716e4367 692 nb_trace =lttv_traceset_number(mw_data->current_tab->traceset_info->traceset);
2176f952 693 name = g_new(char*,nb_trace);
694 for(i = 0; i < nb_trace; i++){
716e4367 695 trace_v = lttv_traceset_get(mw_data->current_tab->
696 traceset_info->traceset, i);
2176f952 697 trace = lttv_trace(trace_v);
a5dcde2f 698 name[i] = ltt_trace_name(trace);
2176f952 699 }
700
701 remove_trace_name = get_remove_trace(name, nb_trace);
702
703 if(remove_trace_name){
704 for(i=0; i<nb_trace; i++){
705 if(strcmp(remove_trace_name,name[i]) == 0){
49bf71b5 706 //unselect the trace from the current viewer
707 w = gtk_multi_vpaned_get_widget(mw_data->current_tab->multi_vpaned);
9f0a7b47 708 if(w){
49bf71b5 709 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
abe346a3 710 if(s){
711 t = lttv_traceset_selector_trace_get(s,i);
712 lttv_trace_selector_set_selected(t, FALSE);
713 }
9f0a7b47 714
715 //check if other viewers select the trace
716 w = gtk_multi_vpaned_get_first_widget(mw_data->current_tab->multi_vpaned);
717 while(w){
718 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
abe346a3 719 if(s){
720 t = lttv_traceset_selector_trace_get(s,i);
721 selected = lttv_trace_selector_get_selected(t);
722 if(selected)break;
723 }
9f0a7b47 724 w = gtk_multi_vpaned_get_next_widget(mw_data->current_tab->multi_vpaned);
725 }
726 }else selected = FALSE;
49bf71b5 727
728 //if no viewer selects the trace, remove it
729 if(!selected){
730 remove_trace_from_traceset_selector(mw_data->current_tab->multi_vpaned, i);
731
732 traceset = mw_data->current_tab->traceset_info->traceset;
733 trace_v = lttv_traceset_get(traceset, i);
734 if(lttv_trace_get_ref_number(trace_v) <= 1)
735 ltt_trace_close(lttv_trace(trace_v));
a43d67ba 736
737 //Keep a reference to the traces so they are not freed.
738 for(j=0; j<lttv_traceset_number(traceset); j++)
739 {
740 LttvTrace * trace = lttv_traceset_get(traceset, j);
741 lttv_trace_ref(trace);
742 }
743
744 //remove state update hooks
745 lttv_state_remove_event_hooks(
746 (LttvTracesetState*)mw_data->current_tab->traceset_info->traceset_context);
747 lttv_context_fini(LTTV_TRACESET_CONTEXT(mw_data->current_tab->traceset_info->traceset_context));
748 g_object_unref(mw_data->current_tab->traceset_info->traceset_context);
749
c2619a30 750
49bf71b5 751 lttv_traceset_remove(traceset, i);
a43d67ba 752 lttv_trace_unref(trace_v); // Remove local reference
912be9a5 753 if(!lttv_trace_get_ref_number(trace_v))
754 lttv_trace_destroy(trace_v);
a43d67ba 755
49bf71b5 756 mw_data->current_tab->traceset_info->traceset_context =
757 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
a43d67ba 758 lttv_context_init(
49bf71b5 759 LTTV_TRACESET_CONTEXT(mw_data->current_tab->
760 traceset_info->traceset_context),traceset);
784705cc 761 //add state update hooks
a43d67ba 762 lttv_state_add_event_hooks(
784705cc 763 (LttvTracesetState*)mw_data->current_tab->traceset_info->traceset_context);
c2619a30 764
a43d67ba 765 //Remove local reference to the traces.
766 for(j=0; j<lttv_traceset_number(traceset); j++)
767 {
768 LttvTrace * trace = lttv_traceset_get(traceset, j);
769 lttv_trace_unref(trace);
770 }
771
c2619a30 772
49bf71b5 773 //update current tab
a43d67ba 774 //update_traceset(mw_data);
912be9a5 775 if(nb_trace > 1){
a43d67ba 776
777 SetTraceset(mw_data, (gpointer)traceset);
778 // in expose now call_pending_read_hooks(mw_data);
779
780 //lttvwindow_report_current_time(mw_data,&(mw_data->current_tab->current_time));
912be9a5 781 }else{
782 if(mw_data->current_tab){
783 while(mw_data->current_tab->multi_vpaned->num_children){
784 gtk_multi_vpaned_widget_delete(mw_data->current_tab->multi_vpaned);
785 }
786 }
787 }
2176f952 788 }
2176f952 789 break;
790 }
791 }
792 }
793
794 g_free(name);
561eba2a 795}
796
abe346a3 797
798/* save will save the traceset to a file
a43d67ba 799 * Not implemented yet FIXME
abe346a3 800 */
801
561eba2a 802void save(GtkWidget * widget, gpointer user_data)
803{
804 g_printf("Save\n");
805}
806
807void save_as(GtkWidget * widget, gpointer user_data)
808{
809 g_printf("Save as\n");
810}
811
abe346a3 812
813/* zoom will change the time_window of all the viewers of the
814 * current tab, and redisplay them. The main functionality is to
815 * determine the new time_window of the current tab
816 */
817
1f1ae829 818void zoom(GtkWidget * widget, double size)
819{
820 TimeInterval *time_span;
a43d67ba 821 TimeWindow new_time_window;
822 LttTime current_time, time_delta, time_s, time_e, time_tmp;
1f1ae829 823 MainWindow * mw_data = get_window_data_struct(widget);
824
fda16332 825 if(size == 1) return;
826
716e4367 827 time_span = LTTV_TRACESET_CONTEXT(mw_data->current_tab->
828 traceset_info->traceset_context)->Time_Span;
a43d67ba 829 new_time_window = mw_data->current_tab->time_window;
1f1ae829 830 current_time = mw_data->current_tab->current_time;
831
832 time_delta = ltt_time_sub(time_span->endTime,time_span->startTime);
833 if(size == 0){
a43d67ba 834 new_time_window.start_time = time_span->startTime;
835 new_time_window.time_width = time_delta;
1f1ae829 836 }else{
a43d67ba 837 new_time_window.time_width = ltt_time_div(new_time_window.time_width, size);
838 if(ltt_time_compare(new_time_window.time_width,time_delta) > 0)
839 { /* Case where zoom out is bigger than trace length */
840 new_time_window.start_time = time_span->startTime;
841 new_time_window.time_width = time_delta;
a8c0f09d 842 }
a43d67ba 843 else
844 {
845 /* Center the image on the current time */
846 g_critical("update is HERE");
847 new_time_window.start_time =
848 ltt_time_sub(current_time, ltt_time_div(new_time_window.time_width, 2.0));
849 /* If on borders, don't fall off */
850 if(ltt_time_compare(new_time_window.start_time, time_span->startTime) <0)
851 {
852 new_time_window.start_time = time_span->startTime;
853 }
854 else
855 {
856 if(ltt_time_compare(
857 ltt_time_add(new_time_window.start_time, new_time_window.time_width),
858 time_span->endTime) > 0)
859 {
860 new_time_window.start_time =
861 ltt_time_sub(time_span->endTime, new_time_window.time_width);
862 }
863 }
864
1f1ae829 865 }
a43d67ba 866
867
868
869 //time_tmp = ltt_time_div(new_time_window.time_width, 2);
870 //if(ltt_time_compare(current_time, time_tmp) < 0){
871 // time_s = time_span->startTime;
872 //} else {
873 // time_s = ltt_time_sub(current_time,time_tmp);
874 //}
875 //time_e = ltt_time_add(current_time,time_tmp);
876 //if(ltt_time_compare(time_span->startTime, time_s) > 0){
877 // time_s = time_span->startTime;
878 //}else if(ltt_time_compare(time_span->endTime, time_e) < 0){
879 // time_e = time_span->endTime;
880 // time_s = ltt_time_sub(time_e,new_time_window.time_width);
881 //}
882 //new_time_window.start_time = time_s;
1f1ae829 883 }
a43d67ba 884
885 //lttvwindow_report_time_window(mw_data, &new_time_window);
886 //call_pending_read_hooks(mw_data);
887
888 //lttvwindow_report_current_time(mw_data,&(mw_data->current_tab->current_time));
889 set_time_window(mw_data, &new_time_window);
890 // in expose now call_pending_read_hooks(mw_data);
891 gtk_multi_vpaned_set_adjust(mw_data->current_tab->multi_vpaned, &new_time_window, FALSE);
1f1ae829 892}
893
561eba2a 894void zoom_in(GtkWidget * widget, gpointer user_data)
895{
1f1ae829 896 zoom(widget, 2);
561eba2a 897}
898
899void zoom_out(GtkWidget * widget, gpointer user_data)
900{
1f1ae829 901 zoom(widget, 0.5);
561eba2a 902}
903
904void zoom_extended(GtkWidget * widget, gpointer user_data)
905{
1f1ae829 906 zoom(widget, 0);
561eba2a 907}
908
909void go_to_time(GtkWidget * widget, gpointer user_data)
910{
911 g_printf("Go to time\n");
912}
913
914void show_time_frame(GtkWidget * widget, gpointer user_data)
915{
916 g_printf("Show time frame\n");
917}
918
919
920/* callback function */
921
922void
923on_empty_traceset_activate (GtkMenuItem *menuitem,
924 gpointer user_data)
925{
68b48a45 926 create_new_window((GtkWidget*)menuitem, user_data, FALSE);
561eba2a 927}
928
929
930void
931on_clone_traceset_activate (GtkMenuItem *menuitem,
932 gpointer user_data)
933{
68b48a45 934 create_new_window((GtkWidget*)menuitem, user_data, TRUE);
561eba2a 935}
936
abe346a3 937
938/* create_new_tab calls create_tab to construct a new tab in the main window
939 */
940
2901f314 941void create_new_tab(GtkWidget* widget, gpointer user_data){
6b1d3120 942 gchar label[PATH_LENGTH];
2901f314 943 MainWindow * mw_data = get_window_data_struct(widget);
944 GtkNotebook * notebook = (GtkNotebook *)lookup_widget(widget, "MNotebook");
561eba2a 945 if(notebook == NULL){
946 g_printf("Notebook does not exist\n");
947 return;
948 }
949
6b1d3120 950 strcpy(label,"Page");
eb38aea5 951 if(get_label(mw_data, label,"Get the name of the tab","Please input tab's name"))
a43d67ba 952 create_tab (NULL, mw_data, notebook, label);
561eba2a 953}
954
2901f314 955void
956on_tab_activate (GtkMenuItem *menuitem,
957 gpointer user_data)
958{
959 create_new_tab((GtkWidget*)menuitem, user_data);
960}
961
561eba2a 962
963void
964on_open_activate (GtkMenuItem *menuitem,
965 gpointer user_data)
966{
967 open_traceset((GtkWidget*)menuitem, user_data);
968}
969
970
971void
972on_close_activate (GtkMenuItem *menuitem,
973 gpointer user_data)
974{
bca3b81f 975 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
68b48a45 976 main_window_destructor(mw_data);
561eba2a 977}
978
979
abe346a3 980/* remove the current tab from the main window if it is not the default tab
981 */
982
561eba2a 983void
984on_close_tab_activate (GtkMenuItem *menuitem,
985 gpointer user_data)
986{
efde9138 987 GList * list;
2061e03d 988 int count = 0;
989 GtkWidget * notebook;
bca3b81f 990 Tab * tmp;
991 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2061e03d 992 notebook = lookup_widget((GtkWidget*)menuitem, "MNotebook");
993 if(notebook == NULL){
994 g_printf("Notebook does not exist\n");
995 return;
996 }
997
bca3b81f 998 if(mw_data->tab == mw_data->current_tab){
999 // tmp = mw_data->current_tb;
1000 // mw_data->tab = mw_data->current_tab->next;
2061e03d 1001 g_printf("The default TAB can not be deleted\n");
1002 return;
1003 }else{
bca3b81f 1004 tmp = mw_data->tab;
1005 while(tmp != mw_data->current_tab){
1006 tmp = tmp->next;
abe346a3 1007 count++;
2061e03d 1008 }
1009 }
1010
1011 gtk_notebook_remove_page((GtkNotebook*)notebook, count);
efde9138 1012 list = gtk_container_get_children(GTK_CONTAINER(notebook));
1013 if(g_list_length(list)==1)
1014 gtk_notebook_set_show_tabs((GtkNotebook*)notebook, FALSE);
561eba2a 1015}
1016
1017
1018void
1019on_add_trace_activate (GtkMenuItem *menuitem,
1020 gpointer user_data)
1021{
1022 add_trace((GtkWidget*)menuitem, user_data);
1023}
1024
1025
1026void
1027on_remove_trace_activate (GtkMenuItem *menuitem,
1028 gpointer user_data)
1029{
1030 remove_trace((GtkWidget*)menuitem, user_data);
1031}
1032
1033
1034void
1035on_save_activate (GtkMenuItem *menuitem,
1036 gpointer user_data)
1037{
1038 save((GtkWidget*)menuitem, user_data);
1039}
1040
1041
1042void
1043on_save_as_activate (GtkMenuItem *menuitem,
1044 gpointer user_data)
1045{
1046 save_as((GtkWidget*)menuitem, user_data);
1047}
1048
1049
1050void
1051on_quit_activate (GtkMenuItem *menuitem,
1052 gpointer user_data)
1053{
2061e03d 1054 gtk_main_quit ();
561eba2a 1055}
1056
1057
1058void
1059on_cut_activate (GtkMenuItem *menuitem,
1060 gpointer user_data)
1061{
1062 g_printf("Cut\n");
1063}
1064
1065
1066void
1067on_copy_activate (GtkMenuItem *menuitem,
1068 gpointer user_data)
1069{
1070 g_printf("Copye\n");
1071}
1072
1073
1074void
1075on_paste_activate (GtkMenuItem *menuitem,
1076 gpointer user_data)
1077{
1078 g_printf("Paste\n");
1079}
1080
1081
1082void
1083on_delete_activate (GtkMenuItem *menuitem,
1084 gpointer user_data)
1085{
1086 g_printf("Delete\n");
1087}
1088
1089
1090void
1091on_zoom_in_activate (GtkMenuItem *menuitem,
1092 gpointer user_data)
1093{
1094 zoom_in((GtkWidget*)menuitem, user_data);
1095}
1096
1097
1098void
1099on_zoom_out_activate (GtkMenuItem *menuitem,
1100 gpointer user_data)
1101{
1102 zoom_out((GtkWidget*)menuitem, user_data);
1103}
1104
1105
1106void
1107on_zoom_extended_activate (GtkMenuItem *menuitem,
1108 gpointer user_data)
1109{
1110 zoom_extended((GtkWidget*)menuitem, user_data);
1111}
1112
1113
1114void
1115on_go_to_time_activate (GtkMenuItem *menuitem,
1116 gpointer user_data)
1117{
1118 go_to_time((GtkWidget*)menuitem, user_data);
1119}
1120
1121
1122void
1123on_show_time_frame_activate (GtkMenuItem *menuitem,
1124 gpointer user_data)
1125{
1126 show_time_frame((GtkWidget*)menuitem, user_data);
1127}
1128
1129
1130void
1131on_move_viewer_up_activate (GtkMenuItem *menuitem,
1132 gpointer user_data)
1133{
1134 move_up_viewer((GtkWidget*)menuitem, user_data);
1135}
1136
1137
1138void
1139on_move_viewer_down_activate (GtkMenuItem *menuitem,
1140 gpointer user_data)
1141{
1142 move_down_viewer((GtkWidget*)menuitem, user_data);
1143}
1144
1145
1146void
1147on_remove_viewer_activate (GtkMenuItem *menuitem,
1148 gpointer user_data)
1149{
1150 delete_viewer((GtkWidget*)menuitem, user_data);
1151}
1152
49bf71b5 1153void
1154on_trace_filter_activate (GtkMenuItem *menuitem,
1155 gpointer user_data)
1156{
1157 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
1158 LttvTracesetSelector * s;
1159 GtkWidget * w = gtk_multi_vpaned_get_widget(mw_data->current_tab->multi_vpaned);
1160
1161 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1162 if(!s){
1163 g_printf("There is no viewer yet\n");
1164 return;
1165 }
a8c0f09d 1166 if(get_filter_selection(s, "Configure trace and tracefile filter", "Select traces and tracefiles")){
a43d67ba 1167 //FIXME report filter change
1168 //update_traceset(mw_data);
1169 //call_pending_read_hooks(mw_data);
1170 //lttvwindow_report_current_time(mw_data,&(mw_data->current_tab->current_time));
a8c0f09d 1171 }
49bf71b5 1172}
1173
1174void
1175on_trace_facility_activate (GtkMenuItem *menuitem,
1176 gpointer user_data)
1177{
1178 g_printf("Trace facility selector: %s\n");
1179}
561eba2a 1180
abe346a3 1181
1182/* Dispaly a file selection dialogue to let user select a module, then call
1183 * lttv_module_load(), finally insert tool button and menu entry in the main window
1184 * for the loaded module
1185 */
1186
561eba2a 1187void
1188on_load_module_activate (GtkMenuItem *menuitem,
1189 gpointer user_data)
1190{
36b3c068 1191 char ** dir;
1192 gint id;
3872a20e 1193 char str[PATH_LENGTH], *str1;
bca3b81f 1194 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
68b48a45 1195 GtkFileSelection * file_selector = (GtkFileSelection *)gtk_file_selection_new("Select a module");
3658a338 1196 if(remember_plugins_dir[0] != '\0')
1197 gtk_file_selection_set_filename(file_selector, remember_plugins_dir);
68b48a45 1198 gtk_file_selection_hide_fileop_buttons(file_selector);
36b3c068 1199
1200 str[0] = '\0';
68b48a45 1201 id = gtk_dialog_run(GTK_DIALOG(file_selector));
36b3c068 1202 switch(id){
1203 case GTK_RESPONSE_ACCEPT:
1204 case GTK_RESPONSE_OK:
68b48a45 1205 dir = gtk_file_selection_get_selections (file_selector);
6fbb1ddf 1206 strncpy(str,dir[0],PATH_LENGTH);
3658a338 1207 strncpy(remember_plugins_dir,dir[0],PATH_LENGTH);
3872a20e 1208 str1 = strrchr(str,'/');
1209 if(str1)str1++;
1210 else{
1211 str1 = strrchr(str,'\\');
1212 str1++;
1213 }
08b1c66e 1214 lttv_module_require(str1, NULL);
f2d17b4d 1215 g_slist_foreach(g_main_window_list, (gpointer)insert_menu_toolbar_item,
1216 NULL);
36b3c068 1217 g_strfreev(dir);
1218 case GTK_RESPONSE_REJECT:
1219 case GTK_RESPONSE_CANCEL:
1220 default:
68b48a45 1221 gtk_widget_destroy((GtkWidget*)file_selector);
36b3c068 1222 break;
1223 }
1224 g_printf("Load module: %s\n", str);
561eba2a 1225}
1226
1227
abe346a3 1228/* Display all loaded modules, let user to select a module to unload
1229 * by calling lttv_module_unload
1230 */
1231
561eba2a 1232void
1233on_unload_module_activate (GtkMenuItem *menuitem,
1234 gpointer user_data)
1235{
36b3c068 1236 int i;
08b1c66e 1237 GPtrArray *name;
1238 char *unload_module_name;
36b3c068 1239 guint nb;
08b1c66e 1240 LttvLibrary *library;
1241 LttvLibraryInfo library_info;
bca3b81f 1242 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
36b3c068 1243
08b1c66e 1244 name = g_ptr_array_new();
1245 nb = lttv_library_number();
1246
36b3c068 1247 for(i=0;i<nb;i++){
08b1c66e 1248 library = lttv_library_get(i);
1249 lttv_library_info(library, &library_info);
1250 if(library_info.load_count > 0) g_ptr_array_add(name, library_info.name);
36b3c068 1251 }
1252
08b1c66e 1253 unload_module_name =get_unload_module((char **)(name->pdata), name->len);
36b3c068 1254
1255 if(unload_module_name){
1256 for(i=0;i<nb;i++){
08b1c66e 1257 library = lttv_library_get(i);
1258 lttv_library_info(library, &library_info);
1259 if(strcmp(unload_module_name, library_info.name) == 0){
1260 lttv_library_unload(library);
36b3c068 1261 break;
1262 }
1263 }
1264 }
1265
08b1c66e 1266 g_ptr_array_free(name, TRUE);
561eba2a 1267}
1268
1269
abe346a3 1270/* Display a directory dialogue to let user select a path for module searching
1271 */
1272
561eba2a 1273void
1274on_add_module_search_path_activate (GtkMenuItem *menuitem,
1275 gpointer user_data)
1276{
68b48a45 1277 GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select module path");
67b98724 1278 const char * dir;
fc188b78 1279 gint id;
1280
bca3b81f 1281 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
3658a338 1282 if(remember_plugins_dir[0] != '\0')
1283 gtk_dir_selection_set_filename(file_selector, remember_plugins_dir);
fc188b78 1284
68b48a45 1285 id = gtk_dialog_run(GTK_DIALOG(file_selector));
fc188b78 1286 switch(id){
1287 case GTK_RESPONSE_ACCEPT:
1288 case GTK_RESPONSE_OK:
68b48a45 1289 dir = gtk_dir_selection_get_dir (file_selector);
3658a338 1290 strncpy(remember_plugins_dir,dir,PATH_LENGTH);
1291 strncat(remember_plugins_dir,"/",PATH_LENGTH);
08b1c66e 1292 lttv_library_path_add(dir);
fc188b78 1293 case GTK_RESPONSE_REJECT:
1294 case GTK_RESPONSE_CANCEL:
1295 default:
68b48a45 1296 gtk_widget_destroy((GtkWidget*)file_selector);
fc188b78 1297 break;
6b1d3120 1298 }
561eba2a 1299}
1300
1301
1302void
1303on_color_activate (GtkMenuItem *menuitem,
1304 gpointer user_data)
1305{
1306 g_printf("Color\n");
1307}
1308
1309
1310void
1311on_filter_activate (GtkMenuItem *menuitem,
1312 gpointer user_data)
1313{
1314 g_printf("Filter\n");
1315}
1316
1317
1318void
1319on_save_configuration_activate (GtkMenuItem *menuitem,
1320 gpointer user_data)
1321{
1322 g_printf("Save configuration\n");
1323}
1324
1325
1326void
1327on_content_activate (GtkMenuItem *menuitem,
1328 gpointer user_data)
1329{
1330 g_printf("Content\n");
1331}
1332
1333
1334void
1335on_about_activate (GtkMenuItem *menuitem,
1336 gpointer user_data)
1337{
1338 g_printf("About...\n");
1339}
1340
1341
1342void
1343on_button_new_clicked (GtkButton *button,
1344 gpointer user_data)
1345{
6f7ad7ae 1346 create_new_window((GtkWidget*)button, user_data, TRUE);
561eba2a 1347}
1348
2901f314 1349void
1350on_button_new_tab_clicked (GtkButton *button,
1351 gpointer user_data)
1352{
1353 create_new_tab((GtkWidget*)button, user_data);
1354}
561eba2a 1355
1356void
1357on_button_open_clicked (GtkButton *button,
1358 gpointer user_data)
1359{
1360 open_traceset((GtkWidget*)button, user_data);
1361}
1362
1363
1364void
1365on_button_add_trace_clicked (GtkButton *button,
1366 gpointer user_data)
1367{
1368 add_trace((GtkWidget*)button, user_data);
1369}
1370
1371
1372void
1373on_button_remove_trace_clicked (GtkButton *button,
1374 gpointer user_data)
1375{
1376 remove_trace((GtkWidget*)button, user_data);
1377}
1378
1379
1380void
1381on_button_save_clicked (GtkButton *button,
1382 gpointer user_data)
1383{
1384 save((GtkWidget*)button, user_data);
1385}
1386
1387
1388void
1389on_button_save_as_clicked (GtkButton *button,
1390 gpointer user_data)
1391{
1392 save_as((GtkWidget*)button, user_data);
1393}
1394
1395
1396void
1397on_button_zoom_in_clicked (GtkButton *button,
1398 gpointer user_data)
1399{
1400 zoom_in((GtkWidget*)button, user_data);
1401}
1402
1403
1404void
1405on_button_zoom_out_clicked (GtkButton *button,
1406 gpointer user_data)
1407{
1408 zoom_out((GtkWidget*)button, user_data);
1409}
1410
1411
1412void
1413on_button_zoom_extended_clicked (GtkButton *button,
1414 gpointer user_data)
1415{
1416 zoom_extended((GtkWidget*)button, user_data);
1417}
1418
1419
1420void
1421on_button_go_to_time_clicked (GtkButton *button,
1422 gpointer user_data)
1423{
1424 go_to_time((GtkWidget*)button, user_data);
1425}
1426
1427
1428void
1429on_button_show_time_frame_clicked (GtkButton *button,
1430 gpointer user_data)
1431{
1432 show_time_frame((GtkWidget*)button, user_data);
1433}
1434
1435
1436void
1437on_button_move_up_clicked (GtkButton *button,
1438 gpointer user_data)
1439{
1440 move_up_viewer((GtkWidget*)button, user_data);
1441}
1442
1443
1444void
1445on_button_move_down_clicked (GtkButton *button,
1446 gpointer user_data)
1447{
1448 move_down_viewer((GtkWidget*)button, user_data);
1449}
1450
1451
1452void
1453on_button_delete_viewer_clicked (GtkButton *button,
1454 gpointer user_data)
1455{
1456 delete_viewer((GtkWidget*)button, user_data);
1457}
1458
1459void
1460on_MWindow_destroy (GtkObject *object,
1461 gpointer user_data)
1462{
e4d09234 1463 MainWindow *Main_Window = get_window_data_struct((GtkWidget*)object);
1464 GtkWidget *widget;
1465 Tab *tab = Main_Window->tab;
1466
68b48a45 1467 g_printf("There are : %d windows\n",g_slist_length(g_main_window_list));
561eba2a 1468
68b48a45 1469 g_win_count--;
1470 if(g_win_count == 0)
7a859036 1471 gtk_main_quit ();
561eba2a 1472}
1473
58eecf4a 1474gboolean
1475on_MWindow_configure (GtkWidget *widget,
1476 GdkEventConfigure *event,
1477 gpointer user_data)
1478{
1479 MainWindow * mw_data = get_window_data_struct((GtkWidget*)widget);
1480 float width = event->width;
1481 Tab * tab = mw_data->tab;
1482 TimeWindow time_win;
1483 double ratio;
1484 TimeInterval *time_span;
1485 LttTime time;
bd24a9af 1486
1487 // MD : removed time width modification upon resizing of the main window.
1488 // The viewers will redraw themselves completely, without time interval
1489 // modification.
1490/* while(tab){
58eecf4a 1491 if(mw_data->window_width){
1492 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
1493 time_win = tab->time_window;
1494 ratio = width / mw_data->window_width;
1495 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
1496 time = ltt_time_sub(time_span->endTime, time_win.start_time);
1497 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
1498 tab->time_window.time_width = time;
1499 }
1500 }
1501 tab = tab->next;
1502 }
1503
1504 mw_data->window_width = (int)width;
bd24a9af 1505 */
58eecf4a 1506 return FALSE;
1507}
561eba2a 1508
abe346a3 1509/* Set current tab
1510 */
1511
561eba2a 1512void
1513on_MNotebook_switch_page (GtkNotebook *notebook,
1514 GtkNotebookPage *page,
1515 guint page_num,
1516 gpointer user_data)
1517{
bca3b81f 1518 MainWindow * mw = get_window_data_struct((GtkWidget*)notebook);
1519 Tab * tab = mw->tab;
561eba2a 1520
1521 while(page_num){
bca3b81f 1522 tab = tab->next;
561eba2a 1523 page_num--;
1524 }
bca3b81f 1525 mw->current_tab = tab;
561eba2a 1526}
1527
abe346a3 1528
1529/* callback function to check or uncheck the check box (filter)
1530 */
1531
49bf71b5 1532void checkbox_changed(GtkTreeView *treeview,
1533 GtkTreePath *arg1,
1534 GtkTreeViewColumn *arg2,
1535 gpointer user_data)
1536{
1537 GtkTreeStore * store = (GtkTreeStore *)gtk_tree_view_get_model (treeview);
1538 GtkTreeIter iter;
1539 gboolean value;
1540
1541 if (gtk_tree_model_get_iter ((GtkTreeModel *)store, &iter, arg1)){
1542 gtk_tree_model_get ((GtkTreeModel *)store, &iter, CHECKBOX_COLUMN, &value, -1);
1543 value = value? FALSE : TRUE;
1544 gtk_tree_store_set (GTK_TREE_STORE (store), &iter, CHECKBOX_COLUMN, value, -1);
1545 }
1546
1547}
1548
abe346a3 1549
1550/* According to user's selection, update selector(filter)
1551 */
1552
49bf71b5 1553void update_filter(LttvTracesetSelector *s, GtkTreeStore *store )
1554{
ed3b99b6 1555 GtkTreeIter iter, child_iter, child_iter1, child_iter2;
1556 int i, j, k, nb_eventtype;
49bf71b5 1557 LttvTraceSelector * trace;
1558 LttvTracefileSelector * tracefile;
ed3b99b6 1559 LttvEventtypeSelector * eventtype;
1560 gboolean value, value1, value2;
49bf71b5 1561
1562 if(gtk_tree_model_get_iter_first((GtkTreeModel*)store, &iter)){
1563 i = 0;
1564 do{
ed3b99b6 1565 trace = lttv_traceset_selector_trace_get(s, i);
1566 nb_eventtype = lttv_trace_selector_eventtype_number(trace);
49bf71b5 1567 gtk_tree_model_get ((GtkTreeModel*)store, &iter, CHECKBOX_COLUMN, &value,-1);
1568 if(value){
1569 j = 0;
1570 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter, &iter)){
1571 do{
ed3b99b6 1572 if(j<1){//eventtype selector for trace
1573 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter, CHECKBOX_COLUMN, &value2,-1);
1574 if(value2){
1575 k=0;
1576 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter1, &child_iter)){
1577 do{
1578 eventtype = lttv_trace_selector_eventtype_get(trace,k);
1579 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter1, CHECKBOX_COLUMN, &value2,-1);
1580 lttv_eventtype_selector_set_selected(eventtype,value2);
1581 k++;
1582 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter1));
1583 }
1584 }
1585 }else{ //tracefile selector
1586 tracefile = lttv_trace_selector_tracefile_get(trace, j - 1);
1587 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter, CHECKBOX_COLUMN, &value1,-1);
1588 lttv_tracefile_selector_set_selected(tracefile,value1);
1589 if(value1){
1590 gtk_tree_model_iter_children((GtkTreeModel*)store, &child_iter1, &child_iter); //eventtype selector
1591 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter1, CHECKBOX_COLUMN, &value2,-1);
1592 if(value2){
1593 k = 0;
1594 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter2, &child_iter1)){
1595 do{//eventtype selector for tracefile
1596 eventtype = lttv_tracefile_selector_eventtype_get(tracefile,k);
1597 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter2, CHECKBOX_COLUMN, &value2,-1);
1598 lttv_eventtype_selector_set_selected(eventtype,value2);
1599 k++;
1600 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter2));
1601 }
1602 }
1603 }
1604 }
49bf71b5 1605 j++;
1606 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter));
1607 }
1608 }
1609 lttv_trace_selector_set_selected(trace,value);
1610 i++;
1611 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &iter));
1612 }
1613}
1614
abe346a3 1615
1616/* Display a dialogue showing all eventtypes and traces, let user to select the interested
1617 * eventtypes, tracefiles and traces (filter)
1618 */
1619
a8c0f09d 1620gboolean get_filter_selection(LttvTracesetSelector *s,char *title, char * column_title)
49bf71b5 1621{
1622 GtkWidget * dialogue;
1623 GtkTreeStore * store;
1624 GtkWidget * tree;
1625 GtkWidget * scroll_win;
1626 GtkCellRenderer * renderer;
1627 GtkTreeViewColumn * column;
ed3b99b6 1628 GtkTreeIter iter, child_iter, child_iter1, child_iter2;
1629 int i, j, k, id, nb_trace, nb_tracefile, nb_eventtype;
49bf71b5 1630 LttvTraceSelector * trace;
1631 LttvTracefileSelector * tracefile;
ed3b99b6 1632 LttvEventtypeSelector * eventtype;
49bf71b5 1633 char * name;
1634 gboolean checked;
1635
1636 dialogue = gtk_dialog_new_with_buttons(title,
1637 NULL,
1638 GTK_DIALOG_MODAL,
1639 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
1640 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
1641 NULL);
ed3b99b6 1642 gtk_window_set_default_size((GtkWindow*)dialogue, 300, 500);
49bf71b5 1643
1644 store = gtk_tree_store_new (TOTAL_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING);
1645 tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
1646 g_object_unref (G_OBJECT (store));
1647 g_signal_connect (G_OBJECT (tree), "row-activated",
1648 G_CALLBACK (checkbox_changed),
1649 NULL);
1650
1651
1652 renderer = gtk_cell_renderer_toggle_new ();
1653 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle *)renderer, FALSE);
1654
1655 g_object_set (G_OBJECT (renderer),"activatable", TRUE, NULL);
1656
1657 column = gtk_tree_view_column_new_with_attributes ("Checkbox",
1658 renderer,
1659 "active", CHECKBOX_COLUMN,
1660 NULL);
1661 gtk_tree_view_column_set_alignment (column, 0.5);
1662 gtk_tree_view_column_set_fixed_width (column, 20);
1663 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
1664
1665 renderer = gtk_cell_renderer_text_new ();
1666 column = gtk_tree_view_column_new_with_attributes (column_title,
1667 renderer,
1668 "text", NAME_COLUMN,
1669 NULL);
1670 gtk_tree_view_column_set_alignment (column, 0.0);
1671 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
1672 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree), FALSE);
1673
1674 scroll_win = gtk_scrolled_window_new (NULL, NULL);
1675 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
1676 GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
1677 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
1678
1679 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
1680
1681 gtk_widget_show(scroll_win);
1682 gtk_widget_show(tree);
1683
ed3b99b6 1684 nb_trace = lttv_traceset_selector_trace_number(s);
49bf71b5 1685 for(i=0;i<nb_trace;i++){
ed3b99b6 1686 trace = lttv_traceset_selector_trace_get(s, i);
49bf71b5 1687 name = lttv_trace_selector_get_name(trace);
1688 gtk_tree_store_append (store, &iter, NULL);
1689 checked = lttv_trace_selector_get_selected(trace);
1690 gtk_tree_store_set (store, &iter,
1691 CHECKBOX_COLUMN,checked,
1692 NAME_COLUMN,name,
1693 -1);
ed3b99b6 1694
1695 gtk_tree_store_append (store, &child_iter, &iter);
1696 gtk_tree_store_set (store, &child_iter,
1697 CHECKBOX_COLUMN, checked,
1698 NAME_COLUMN,"eventtype",
1699 -1);
1700
1701 nb_eventtype = lttv_trace_selector_eventtype_number(trace);
1702 for(j=0;j<nb_eventtype;j++){
1703 eventtype = lttv_trace_selector_eventtype_get(trace,j);
1704 name = lttv_eventtype_selector_get_name(eventtype);
1705 checked = lttv_eventtype_selector_get_selected(eventtype);
1706 gtk_tree_store_append (store, &child_iter1, &child_iter);
1707 gtk_tree_store_set (store, &child_iter1,
1708 CHECKBOX_COLUMN, checked,
1709 NAME_COLUMN,name,
1710 -1);
1711 }
1712
1713 nb_tracefile = lttv_trace_selector_tracefile_number(trace);
49bf71b5 1714 for(j=0;j<nb_tracefile;j++){
ed3b99b6 1715 tracefile = lttv_trace_selector_tracefile_get(trace, j);
49bf71b5 1716 name = lttv_tracefile_selector_get_name(tracefile);
1717 gtk_tree_store_append (store, &child_iter, &iter);
1718 checked = lttv_tracefile_selector_get_selected(tracefile);
1719 gtk_tree_store_set (store, &child_iter,
1720 CHECKBOX_COLUMN, checked,
1721 NAME_COLUMN,name,
1722 -1);
ed3b99b6 1723
1724 gtk_tree_store_append (store, &child_iter1, &child_iter);
1725 gtk_tree_store_set (store, &child_iter1,
1726 CHECKBOX_COLUMN, checked,
1727 NAME_COLUMN,"eventtype",
1728 -1);
1729
1730 for(k=0;k<nb_eventtype;k++){
1731 eventtype = lttv_tracefile_selector_eventtype_get(tracefile,k);
1732 name = lttv_eventtype_selector_get_name(eventtype);
1733 checked = lttv_eventtype_selector_get_selected(eventtype);
1734 gtk_tree_store_append (store, &child_iter2, &child_iter1);
1735 gtk_tree_store_set (store, &child_iter2,
1736 CHECKBOX_COLUMN, checked,
1737 NAME_COLUMN,name,
1738 -1);
1739 }
49bf71b5 1740 }
1741 }
1742
1743 id = gtk_dialog_run(GTK_DIALOG(dialogue));
1744 switch(id){
1745 case GTK_RESPONSE_ACCEPT:
1746 case GTK_RESPONSE_OK:
1747 update_filter(s, store);
a8c0f09d 1748 gtk_widget_destroy(dialogue);
1749 return TRUE;
49bf71b5 1750 case GTK_RESPONSE_REJECT:
1751 case GTK_RESPONSE_CANCEL:
1752 default:
1753 gtk_widget_destroy(dialogue);
1754 break;
1755 }
a8c0f09d 1756 return FALSE;
49bf71b5 1757}
1758
abe346a3 1759
1760/* Select a trace which will be removed from traceset
1761 */
1762
2176f952 1763char * get_remove_trace(char ** all_trace_name, int nb_trace)
1764{
1765 return get_selection(all_trace_name, nb_trace,
1766 "Select a trace", "Trace pathname");
1767}
abe346a3 1768
1769
1770/* Select a module which will be unloaded
1771 */
1772
36b3c068 1773char * get_unload_module(char ** loaded_module_name, int nb_module)
2176f952 1774{
1775 return get_selection(loaded_module_name, nb_module,
1776 "Select an unload module", "Module pathname");
1777}
1778
abe346a3 1779
1780/* Display a dialogue which shows all selectable items, let user to
1781 * select one of them
1782 */
1783
2176f952 1784char * get_selection(char ** loaded_module_name, int nb_module,
1785 char *title, char * column_title)
36b3c068 1786{
1787 GtkWidget * dialogue;
1788 GtkWidget * scroll_win;
1789 GtkWidget * tree;
1790 GtkListStore * store;
1791 GtkTreeViewColumn * column;
1792 GtkCellRenderer * renderer;
1793 GtkTreeSelection * select;
1794 GtkTreeIter iter;
1795 gint id, i;
1796 char * unload_module_name = NULL;
1797
2176f952 1798 dialogue = gtk_dialog_new_with_buttons(title,
36b3c068 1799 NULL,
1800 GTK_DIALOG_MODAL,
1801 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
1802 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
1803 NULL);
1804 gtk_window_set_default_size((GtkWindow*)dialogue, 500, 200);
1805
1806 scroll_win = gtk_scrolled_window_new (NULL, NULL);
1807 gtk_widget_show ( scroll_win);
1808 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
1809 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1810
1811 store = gtk_list_store_new (N_COLUMNS,G_TYPE_STRING);
1812 tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL (store));
1813 gtk_widget_show ( tree);
1814 g_object_unref (G_OBJECT (store));
1815
1816 renderer = gtk_cell_renderer_text_new ();
2176f952 1817 column = gtk_tree_view_column_new_with_attributes (column_title,
36b3c068 1818 renderer,
1819 "text", MODULE_COLUMN,
1820 NULL);
1821 gtk_tree_view_column_set_alignment (column, 0.5);
1822 gtk_tree_view_column_set_fixed_width (column, 150);
1823 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
1824
1825 select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
1826 gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
1827
1828 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
1829
1830 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
1831
1832 for(i=0;i<nb_module;i++){
1833 gtk_list_store_append (store, &iter);
1834 gtk_list_store_set (store, &iter, MODULE_COLUMN,loaded_module_name[i],-1);
1835 }
1836
1837 id = gtk_dialog_run(GTK_DIALOG(dialogue));
1838 switch(id){
1839 case GTK_RESPONSE_ACCEPT:
1840 case GTK_RESPONSE_OK:
1841 if (gtk_tree_selection_get_selected (select, (GtkTreeModel**)&store, &iter)){
1842 gtk_tree_model_get ((GtkTreeModel*)store, &iter, MODULE_COLUMN, &unload_module_name, -1);
1843 }
1844 case GTK_RESPONSE_REJECT:
1845 case GTK_RESPONSE_CANCEL:
1846 default:
1847 gtk_widget_destroy(dialogue);
1848 break;
1849 }
1850
1851 return unload_module_name;
1852}
5723fa24 1853
abe346a3 1854
1855/* hash funtions
1856 */
1857
2176f952 1858void main_window_destroy_hash_key(gpointer key)
2061e03d 1859{
1860 g_free(key);
1861}
1862
2176f952 1863void main_window_destroy_hash_data(gpointer data)
2061e03d 1864{
1865}
1866
1867
abe346a3 1868/* Insert menu entry and tool button into all main windows for modules
1869 * It checks whether the menu entry or tool button exists or not,
1870 * if they do not exist, then construct the widget and insert them
1871 * into all main windows
1872 */
1873
bca3b81f 1874void insert_menu_toolbar_item(MainWindow * mw, gpointer user_data)
5723fa24 1875{
1876 int i;
1877 GdkPixbuf *pixbuf;
42fcbb71 1878 lttvwindow_viewer_constructor constructor;
5723fa24 1879 LttvMenus * menu;
1880 LttvToolbars * toolbar;
68b48a45 1881 lttv_menu_closure *menu_item;
1882 lttv_toolbar_closure *toolbar_item;
5723fa24 1883 LttvAttributeValue value;
1884 LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
68b48a45 1885 GtkWidget * tool_menu_title_menu, *insert_view, *pixmap, *tmp;
5723fa24 1886
1887 g_assert(lttv_iattribute_find_by_path(attributes,
1888 "viewers/menu", LTTV_POINTER, &value));
1889 menu = (LttvMenus*)*(value.v_pointer);
1890
1891 if(menu){
1892 for(i=0;i<menu->len;i++){
68b48a45 1893 menu_item = &g_array_index(menu, lttv_menu_closure, i);
1894 tmp = g_hash_table_lookup(mw->hash_menu_item, g_strdup(menu_item->menuText));
3872a20e 1895 if(tmp)continue;
68b48a45 1896 constructor = menu_item->con;
bca3b81f 1897 tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
68b48a45 1898 insert_view = gtk_menu_item_new_with_mnemonic (menu_item->menuText);
5723fa24 1899 gtk_widget_show (insert_view);
68b48a45 1900 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu), insert_view);
5723fa24 1901 g_signal_connect ((gpointer) insert_view, "activate",
68b48a45 1902 G_CALLBACK (insert_viewer_wrap),
5723fa24 1903 constructor);
68b48a45 1904 g_hash_table_insert(mw->hash_menu_item, g_strdup(menu_item->menuText),
2061e03d 1905 insert_view);
5723fa24 1906 }
1907 }
1908
1909 g_assert(lttv_iattribute_find_by_path(attributes,
1910 "viewers/toolbar", LTTV_POINTER, &value));
1911 toolbar = (LttvToolbars*)*(value.v_pointer);
1912
1913 if(toolbar){
1914 for(i=0;i<toolbar->len;i++){
68b48a45 1915 toolbar_item = &g_array_index(toolbar, lttv_toolbar_closure, i);
1916 tmp = g_hash_table_lookup(mw->hash_toolbar_item, g_strdup(toolbar_item->tooltip));
3872a20e 1917 if(tmp)continue;
68b48a45 1918 constructor = toolbar_item->con;
efde9138 1919 tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1");
68b48a45 1920 pixbuf = gdk_pixbuf_new_from_xpm_data ((const char**)toolbar_item->pixmap);
5723fa24 1921 pixmap = gtk_image_new_from_pixbuf(pixbuf);
68b48a45 1922 insert_view = gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu),
5723fa24 1923 GTK_TOOLBAR_CHILD_BUTTON,
1924 NULL,
1925 "",
68b48a45 1926 toolbar_item->tooltip, NULL,
5723fa24 1927 pixmap, NULL, NULL);
68b48a45 1928 gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (tool_menu_title_menu)->children)->data))->label), TRUE);
5723fa24 1929 gtk_widget_show (insert_view);
1930 gtk_container_set_border_width (GTK_CONTAINER (insert_view), 1);
68b48a45 1931 g_signal_connect ((gpointer) insert_view, "clicked",G_CALLBACK (insert_viewer_wrap),constructor);
1932 g_hash_table_insert(mw->hash_toolbar_item, g_strdup(toolbar_item->tooltip),
2061e03d 1933 insert_view);
5723fa24 1934 }
1935 }
1936}
1937
abe346a3 1938
1939/* Create a main window
1940 */
1941
08b1c66e 1942void construct_main_window(MainWindow * parent)
5723fa24 1943{
2a2fa4f0 1944 g_debug("construct_main_window()");
68b48a45 1945 GtkWidget * new_window; /* New generated main window */
bca3b81f 1946 MainWindow * new_m_window;/* New main window structure */
5723fa24 1947 GtkNotebook * notebook;
f7afe191 1948 LttvIAttribute *attributes =
1949 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
1950 LttvAttributeValue value;
2061e03d 1951
bca3b81f 1952 new_m_window = g_new(MainWindow, 1);
5723fa24 1953
1954 // Add the object's information to the module's array
68b48a45 1955 g_main_window_list = g_slist_append(g_main_window_list, new_m_window);
5723fa24 1956
f7afe191 1957
68b48a45 1958 new_window = create_MWindow();
1959 gtk_widget_show (new_window);
5723fa24 1960
bca3b81f 1961 new_m_window->mwindow = new_window;
1962 new_m_window->tab = NULL;
1963 new_m_window->current_tab = NULL;
a43d67ba 1964 new_m_window->attributes = attributes;
5723fa24 1965
68b48a45 1966 new_m_window->hash_menu_item = g_hash_table_new_full (g_str_hash, g_str_equal,
2176f952 1967 main_window_destroy_hash_key,
1968 main_window_destroy_hash_data);
68b48a45 1969 new_m_window->hash_toolbar_item = g_hash_table_new_full (g_str_hash, g_str_equal,
2176f952 1970 main_window_destroy_hash_key,
1971 main_window_destroy_hash_data);
2061e03d 1972
68b48a45 1973 insert_menu_toolbar_item(new_m_window, NULL);
5723fa24 1974
68b48a45 1975 g_object_set_data(G_OBJECT(new_window), "mainWindow", (gpointer)new_m_window);
5723fa24 1976 //create a default tab
bca3b81f 1977 notebook = (GtkNotebook *)lookup_widget(new_m_window->mwindow, "MNotebook");
5723fa24 1978 if(notebook == NULL){
1979 g_printf("Notebook does not exist\n");
1980 return;
1981 }
1982 //for now there is no name field in LttvTraceset structure
1983 //Use "Traceset" as the label for the default tab
a43d67ba 1984 create_tab(parent, new_m_window, notebook, "Traceset");
5723fa24 1985
7a859036 1986 g_object_set_data_full(
bca3b81f 1987 G_OBJECT(new_m_window->mwindow),
7a859036 1988 "Main_Window_Data",
68b48a45 1989 new_m_window,
1990 (GDestroyNotify)main_window_free);
7a859036 1991
68b48a45 1992 g_win_count++;
5723fa24 1993}
1994
abe346a3 1995
1996/* Free the memory occupied by a tab structure
1997 * destroy the tab
1998 */
1999
bca3b81f 2000void tab_destructor(Tab * tab_instance)
f7afe191 2001{
716e4367 2002 int i, nb, ref_count;
2003 LttvTrace * trace;
2004
bca3b81f 2005 if(tab_instance->attributes)
2006 g_object_unref(tab_instance->attributes);
2061e03d 2007
bca3b81f 2008 if(tab_instance->mw->tab == tab_instance){
2009 tab_instance->mw->tab = tab_instance->next;
2061e03d 2010 }else{
bca3b81f 2011 Tab * tmp1, *tmp = tab_instance->mw->tab;
68b48a45 2012 while(tmp != tab_instance){
2061e03d 2013 tmp1 = tmp;
bca3b81f 2014 tmp = tmp->next;
2061e03d 2015 }
bca3b81f 2016 tmp1->next = tab_instance->next;
2061e03d 2017 }
716e4367 2018
2019 if(tab_instance->traceset_info->traceset_context != NULL){
784705cc 2020 //remove state update hooks
2021 lttv_state_remove_event_hooks(
2022 (LttvTracesetState*)tab_instance->traceset_info->
2023 traceset_context);
716e4367 2024 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab_instance->traceset_info->
2025 traceset_context));
2026 g_object_unref(tab_instance->traceset_info->traceset_context);
2027 }
2028 if(tab_instance->traceset_info->traceset != NULL) {
2029 nb = lttv_traceset_number(tab_instance->traceset_info->traceset);
2030 for(i = 0 ; i < nb ; i++) {
2031 trace = lttv_traceset_get(tab_instance->traceset_info->traceset, i);
2032 ref_count = lttv_trace_get_ref_number(trace);
49bf71b5 2033 if(ref_count <= 1){
716e4367 2034 ltt_trace_close(lttv_trace(trace));
6f7ad7ae 2035 lttv_trace_destroy(trace);
49bf71b5 2036 }
6f7ad7ae 2037 // lttv_trace_destroy(trace);
716e4367 2038 }
2039 }
a43d67ba 2040 lttv_traceset_destroy(tab_instance->traceset_info->traceset);
2041 g_array_free(tab_instance->time_requests, TRUE);
716e4367 2042 g_free(tab_instance->traceset_info);
68b48a45 2043 g_free(tab_instance);
f7afe191 2044}
2045
abe346a3 2046
2047/* Create a tab and insert it into the current main window
2048 */
2049
716e4367 2050void * create_tab(MainWindow * parent, MainWindow* current_window,
2051 GtkNotebook * notebook, char * label)
5723fa24 2052{
2053 GList * list;
bca3b81f 2054 Tab * tmp_tab;
716e4367 2055 MainWindow * mw_data = current_window;
68b48a45 2056 LttTime tmp_time;
a43d67ba 2057
abe346a3 2058 //create a new tab data structure
bca3b81f 2059 tmp_tab = mw_data->tab;
2060 while(tmp_tab && tmp_tab->next) tmp_tab = tmp_tab->next;
68b48a45 2061 if(!tmp_tab){
bca3b81f 2062 mw_data->current_tab = NULL;
2063 tmp_tab = g_new(Tab,1);
2064 mw_data->tab = tmp_tab;
5723fa24 2065 }else{
bca3b81f 2066 tmp_tab->next = g_new(Tab,1);
2067 tmp_tab = tmp_tab->next;
5723fa24 2068 }
716e4367 2069
abe346a3 2070 //construct and initialize the traceset_info
716e4367 2071 tmp_tab->traceset_info = g_new(TracesetInfo,1);
2072 if(parent){
a43d67ba 2073 if(parent->current_tab){
2074 tmp_tab->traceset_info->traceset =
2075 lttv_traceset_new();
2076 //FIXME lttv_traceset_copy(parent->current_tab->traceset_info->traceset);
2077 }else{
2078 tmp_tab->traceset_info->traceset = lttv_traceset_new();
2079 }
2080
2081 }else{ /* Initial window */
716e4367 2082 if(mw_data->current_tab){
2083 tmp_tab->traceset_info->traceset =
a43d67ba 2084 lttv_traceset_new();
2085 //FIXME lttv_traceset_copy(mw_data->current_tab->traceset_info->traceset);
716e4367 2086 }else{
2087 tmp_tab->traceset_info->traceset = lttv_traceset_new();
49bf71b5 2088 /* Add the command line trace */
a43d67ba 2089 if(g_init_trace != NULL){
49bf71b5 2090 lttv_traceset_add(tmp_tab->traceset_info->traceset, g_init_trace);
a43d67ba 2091 }
716e4367 2092 }
716e4367 2093 }
a43d67ba 2094
716e4367 2095 //FIXME copy not implemented in lower level
2096 tmp_tab->traceset_info->traceset_context =
2097 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
a43d67ba 2098 g_assert(tmp_tab->traceset_info->traceset_context != NULL);
716e4367 2099 lttv_context_init(
2100 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context),
2101 tmp_tab->traceset_info->traceset);
784705cc 2102 //add state update hooks
2103 lttv_state_add_event_hooks(
2104 (LttvTracesetState*)tmp_tab->traceset_info->traceset_context);
2105
abe346a3 2106 //determine the current_time and time_window of the tab
bca3b81f 2107 if(mw_data->current_tab){
716e4367 2108 // Will have to read directly at the main window level, as we want
2109 // to be able to modify a traceset on the fly.
bca3b81f 2110 tmp_tab->time_window = mw_data->current_tab->time_window;
2111 tmp_tab->current_time = mw_data->current_tab->current_time;
5723fa24 2112 }else{
716e4367 2113 // Will have to read directly at the main window level, as we want
2114 // to be able to modify a traceset on the fly.
2115 // get_traceset_time_span(mw_data,&tmp_tab->traceStartTime, &tmp_tab->traceEndTime);
bca3b81f 2116 tmp_tab->time_window.start_time =
716e4367 2117 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->startTime;
f7afe191 2118 if(DEFAULT_TIME_WIDTH_S <
716e4367 2119 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->endTime.tv_sec)
68b48a45 2120 tmp_time.tv_sec = DEFAULT_TIME_WIDTH_S;
f7afe191 2121 else
68b48a45 2122 tmp_time.tv_sec =
716e4367 2123 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->endTime.tv_sec;
68b48a45 2124 tmp_time.tv_nsec = 0;
bca3b81f 2125 tmp_tab->time_window.time_width = tmp_time ;
a8c0f09d 2126 tmp_tab->current_time.tv_sec =
2127 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->startTime.tv_sec;
2128 tmp_tab->current_time.tv_nsec =
2129 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->startTime.tv_nsec;
5723fa24 2130 }
a43d67ba 2131 /* Become the current tab */
2132 mw_data->current_tab = tmp_tab;
2133
bca3b81f 2134 tmp_tab->attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
daecc161 2135 tmp_tab->multi_vpaned = (GtkMultiVPaned*)gtk_multi_vpaned_new();
2136 tmp_tab->multi_vpaned->mw = mw_data;
2137 gtk_widget_show((GtkWidget*)tmp_tab->multi_vpaned);
bca3b81f 2138 tmp_tab->next = NULL;
68b48a45 2139 tmp_tab->mw = mw_data;
5723fa24 2140
68b48a45 2141 tmp_tab->label = gtk_label_new (label);
2142 gtk_widget_show (tmp_tab->label);
5723fa24 2143
a43d67ba 2144 tmp_tab->time_requests = g_array_new(FALSE, FALSE, sizeof(TimeRequest));
2145 tmp_tab->time_request_pending = FALSE;
2146
f7afe191 2147 g_object_set_data_full(
daecc161 2148 G_OBJECT(tmp_tab->multi_vpaned),
f7afe191 2149 "Tab_Info",
68b48a45 2150 tmp_tab,
2151 (GDestroyNotify)tab_destructor);
540edb40 2152
784705cc 2153 //insert tab into notebook
daecc161 2154 gtk_notebook_append_page(notebook, (GtkWidget*)tmp_tab->multi_vpaned, tmp_tab->label);
5723fa24 2155 list = gtk_container_get_children(GTK_CONTAINER(notebook));
2156 gtk_notebook_set_current_page(notebook,g_list_length(list)-1);
a43d67ba 2157 // always show : not if(g_list_length(list)>1)
2158 gtk_notebook_set_show_tabs(notebook, TRUE);
2159
5723fa24 2160}
2061e03d 2161
abe346a3 2162
2163/* Remove menu entry and tool button from main window for the
2164 * unloaded module
2165 */
2166
2061e03d 2167void remove_menu_item(gpointer main_win, gpointer user_data)
2168{
bca3b81f 2169 MainWindow * mw = (MainWindow *) main_win;
68b48a45 2170 lttv_menu_closure *menu_item = (lttv_menu_closure *)user_data;
2171 GtkWidget * tool_menu_title_menu, *insert_view;
2061e03d 2172
bca3b81f 2173 tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
2061e03d 2174 insert_view = (GtkWidget*)g_hash_table_lookup(mw->hash_menu_item,
68b48a45 2175 menu_item->menuText);
2061e03d 2176 if(insert_view){
68b48a45 2177 g_hash_table_remove(mw->hash_menu_item, menu_item->menuText);
2178 gtk_container_remove (GTK_CONTAINER (tool_menu_title_menu), insert_view);
2061e03d 2179 }
2180}
2181
2182void remove_toolbar_item(gpointer main_win, gpointer user_data)
2183{
bca3b81f 2184 MainWindow * mw = (MainWindow *) main_win;
68b48a45 2185 lttv_toolbar_closure *toolbar_item = (lttv_toolbar_closure *)user_data;
2186 GtkWidget * tool_menu_title_menu, *insert_view;
2061e03d 2187
2188
efde9138 2189 tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1");
2061e03d 2190 insert_view = (GtkWidget*)g_hash_table_lookup(mw->hash_toolbar_item,
68b48a45 2191 toolbar_item->tooltip);
2061e03d 2192 if(insert_view){
68b48a45 2193 g_hash_table_remove(mw->hash_toolbar_item, toolbar_item->tooltip);
2194 gtk_container_remove (GTK_CONTAINER (tool_menu_title_menu), insert_view);
2061e03d 2195 }
2196}
2197
2198/**
abe346a3 2199 * Remove menu and toolbar item when a module unloaded from all
2200 * main windows
2061e03d 2201 */
2176f952 2202
224446ce 2203void main_window_remove_menu_item(lttvwindow_viewer_constructor constructor)
2061e03d 2204{
2205 int i;
2206 LttvMenus * menu;
68b48a45 2207 lttv_menu_closure *menu_item;
2061e03d 2208 LttvAttributeValue value;
2209 LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
2210
2211 g_assert(lttv_iattribute_find_by_path(attributes,
2212 "viewers/menu", LTTV_POINTER, &value));
2213 menu = (LttvMenus*)*(value.v_pointer);
2214
2215 if(menu){
2216 for(i=0;i<menu->len;i++){
68b48a45 2217 menu_item = &g_array_index(menu, lttv_menu_closure, i);
2218 if(menu_item->con != constructor) continue;
2219 if(g_main_window_list){
2220 g_slist_foreach(g_main_window_list, remove_menu_item, menu_item);
2176f952 2221 }
2061e03d 2222 break;
2223 }
2224 }
2225
2226}
2227
224446ce 2228void main_window_remove_toolbar_item(lttvwindow_viewer_constructor constructor)
2061e03d 2229{
2230 int i;
2231 LttvToolbars * toolbar;
68b48a45 2232 lttv_toolbar_closure *toolbar_item;
2061e03d 2233 LttvAttributeValue value;
2234 LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
2235
2236 g_assert(lttv_iattribute_find_by_path(attributes,
2237 "viewers/toolbar", LTTV_POINTER, &value));
2238 toolbar = (LttvToolbars*)*(value.v_pointer);
2239
2240 if(toolbar){
2241 for(i=0;i<toolbar->len;i++){
68b48a45 2242 toolbar_item = &g_array_index(toolbar, lttv_toolbar_closure, i);
2243 if(toolbar_item->con != constructor) continue;
2244 if(g_main_window_list){
2245 g_slist_foreach(g_main_window_list, remove_toolbar_item, toolbar_item);
2176f952 2246 }
2061e03d 2247 break;
2248 }
2249 }
2250}
a43d67ba 2251
2252/**
2253 * Function to show each viewer in the current tab.
2254 * It will be called by main window, call show on each registered viewer,
2255 * will call process traceset and then it will
2256 * @param main_win the main window the viewer belongs to.
2257 */
2258//FIXME Only one time request maximum for now!
2259void show_viewer(MainWindow *main_win)
2260{
2261 LttvAttributeValue value;
2262 LttvHooks * tmp;
2263 int i;
2264 LttvTracesetContext * tsc =
2265 (LttvTracesetContext*)main_win->current_tab->
2266 traceset_info->traceset_context;
2267
2268 g_assert(lttv_iattribute_find_by_path(main_win->current_tab->attributes,
2269 "hooks/showviewer", LTTV_POINTER, &value));
2270 tmp = (LttvHooks*)*(value.v_pointer);
2271 if(tmp == NULL)
2272 {
2273 g_warning("The viewer(s) did not add any show hook");
2274 return;
2275 }
2276
2277
2278 // Call the show, where viewers add hooks to context and fill the
2279 // time and number of events requested it the time_requests GArray.
2280 lttv_hooks_call(tmp, NULL);
2281
2282
2283}
2284
2285
2286gboolean execute_time_requests(MainWindow * mw)
2287{
2288 call_pending_read_hooks(mw);
2289
2290 return FALSE; // automatically removed from the list of event sources
2291}
2292
This page took 0.144217 seconds and 4 git commands to generate.