X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Fmodules%2Fgui%2Flttvwindow%2Flttvwindow%2Fcallbacks.c;h=baea60a9ee018ccf00078ccdce971bdea12510e7;hb=20fde85fa4660fbc6ec44101c8d7e9fe2aca94fa;hp=8f5a612a35519e1591ff02ce93f28f9bcf0f618f;hpb=6c9d86ddd9b3b83e27016d745a2164c0731f2bf3;p=lttv.git diff --git a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c index 8f5a612a..baea60a9 100644 --- a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c +++ b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c @@ -34,9 +34,10 @@ #include #include #include +#include #include #include -#include +#include #include #include @@ -49,8 +50,6 @@ extern LttvTrace *g_init_trace ; /** Array containing instanced objects. */ extern GSList * g_main_window_list; -static int g_win_count = 0; - /** MD : keep old directory. */ static char remember_plugins_dir[PATH_LENGTH] = ""; static char remember_trace_dir[PATH_LENGTH] = ""; @@ -64,7 +63,7 @@ gboolean get_filter_selection(LttvTracesetSelector *s, char *title, char * colum void * create_tab(MainWindow * parent, MainWindow * current_window, GtkNotebook * notebook, char * label); -void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor); +static void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor); void update_filter(LttvTracesetSelector *s, GtkTreeStore *store ); void checkbox_changed(GtkTreeView *treeview, @@ -76,8 +75,7 @@ void add_trace_into_traceset_selector(GtkMultiVPaned * paned, LttTrace * trace); LttvTracesetSelector * construct_traceset_selector(LttvTraceset * traceset); -void call_pending_read_hooks(MainWindow * mw_data); -unsigned get_max_event_number(MainWindow * mw_data); +static gboolean lttvwindow_process_pending_requests(Tab *tab); enum { CHECKBOX_COLUMN, @@ -165,17 +163,17 @@ insert_viewer_wrap(GtkWidget *menuitem, gpointer user_data) void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor) { GtkMultiVPaned * multi_vpaned; - MainWindow * mw_data; + MainWindow * mw_data = get_window_data_struct(widget); GtkWidget * viewer; LttvTracesetSelector * s; TimeInterval * time_interval; + Tab *tab = mw_data->current_tab; - mw_data = get_window_data_struct(widget); - if(!mw_data->current_tab) return; - multi_vpaned = mw_data->current_tab->multi_vpaned; + if(!tab) return; + multi_vpaned = tab->multi_vpaned; - s = construct_traceset_selector(mw_data->current_tab->traceset_info->traceset); - viewer = (GtkWidget*)constructor(mw_data, s, "Traceset_Selector"); + s = construct_traceset_selector(tab->traceset_info->traceset); + viewer = (GtkWidget*)constructor(tab, s, "Traceset_Selector"); if(viewer) { gtk_multi_vpaned_widget_add(multi_vpaned, viewer); @@ -255,13 +253,13 @@ MainWindow * get_window_data_struct(GtkWidget * widget) mw = lookup_widget(widget, "MWindow"); if(mw == NULL){ g_printf("Main window does not exist\n"); - return; + return NULL; } - mw_data = (MainWindow *) g_object_get_data(G_OBJECT(mw),"mainWindow"); + mw_data = (MainWindow *) g_object_get_data(G_OBJECT(mw),"main_window_data"); if(mw_data == NULL){ g_printf("Main window data does not exist\n"); - return; + return NULL; } return mw_data; } @@ -349,154 +347,530 @@ void open_traceset(GtkWidget * widget, gpointer user_data) } -/* get_max_event_number returns the event number limit used by - * lttv_process_traceset(LttvTracesetContext, endTime, maxNumEvents) - * each viewer can set the limit - */ - -unsigned get_max_event_number(MainWindow * mw_data) -{ - unsigned nb = 0, *size; - GtkWidget * w; - - w = gtk_multi_vpaned_get_first_widget(mw_data->current_tab->multi_vpaned); - while(w){ - size = (unsigned*)g_object_get_data(G_OBJECT(w), MAX_NUMBER_EVENT); - if(size == NULL){ - nb = G_MAXULONG; - break; - }else{ - if(nb < *size) - nb = *size; - } - w = gtk_multi_vpaned_get_next_widget(mw_data->current_tab->multi_vpaned); - } - return nb; -} - - -/* call_pending_read_hooks parses the traceset first by calling - * process_traceset, then display all viewers of - * the current tab - * It will then remove all entries from the time_requests array. - * CHECK : we give more events than requested to the viewers. They - * Have to filter them by themselves. +/* lttvwindow_process_pending_requests + * + * This internal function gets called by g_idle, taking care of the pending + * requests. It is responsible for concatenation of time intervals and position + * requests. It does it with the following algorithm organizing process traceset + * calls. Here is the detailed description of the way it works : + * + * - Events Requests Servicing Algorithm + * + * Data structures necessary : + * + * List of requests added to context : list_in + * List of requests not added to context : list_out + * + * Initial state : + * + * list_in : empty + * list_out : many events requests + * + * FIXME : insert rest of algorithm here + * */ -gint compare_time_request(TimeRequest *a, TimeRequest *b) -{ - return ltt_time_compare(a->time_window.start_time, b->time_window.start_time); -} -void call_pending_read_hooks(MainWindow * mw_data) +gboolean lttvwindow_process_pending_requests(Tab *tab) { unsigned max_nb_events; GdkWindow * win; GdkCursor * new; GtkWidget* widget; - int i; LttvTracesetContext *tsc; + LttvTracefileContext *tfc; + GSList *events_requests = tab->events_requests; + GSList *list_out = events_requests; + GSList *list_in = NULL; + LttTime end_time; + guint end_nb_events; + guint count; + LttvTracesetContextPosition *end_position; + /* Current tab check : if no current tab is present, no hooks to call. */ - /* It makes the expose works.. */ - if(mw_data->current_tab == NULL) - return; - - if(mw_data->current_tab->time_requests->len == 0) - return; + /* (Xang Xiu) It makes the expose works.. MD:? */ + if(tab == NULL) + return FALSE; - LttvHooks *tmp_hooks = lttv_hooks_new(); + /* There is no events requests pending : we should never have been called! */ + g_assert(g_slist_length(events_requests) != 0); - tsc = - LTTV_TRACESET_CONTEXT(mw_data->current_tab->traceset_info-> - traceset_context); + tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context); //set the cursor to be X shape, indicating that the computer is busy in doing its job new = gdk_cursor_new(GDK_X_CURSOR); - widget = lookup_widget(mw_data->mwindow, "MToolbar1"); + widget = lookup_widget(tab->mw->mwindow, "MToolbar1"); win = gtk_widget_get_parent_window(widget); gdk_window_set_cursor(win, new); gdk_cursor_unref(new); gdk_window_stick(win); gdk_window_unstick(win); + g_debug("SIZE events req len : %d", g_slist_length(events_requests)); + + /* Events processing algorithm implementation */ + /* A. Servicing loop */ + while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0) + && !gtk_events_pending() ) { - g_array_sort(mw_data->current_tab->time_requests, - (GCompareFunc)compare_time_request); - + /* 1. If list_in is empty (need a seek) */ + if( g_slist_length(list_in) == 0 ) { - //update time window of each viewer, let viewer insert hooks needed by process_traceset - //lttvwindow_report_time_window(mw_data, time_window); - - //max_nb_events = get_max_event_number(mw_data); + /* list in is empty, need a seek */ + { + /* 1.1 Add requests to list_in */ + GSList *ltime = NULL; + GSList *lpos = NULL; + GSList *iter = NULL; + + /* 1.1.1 Find all time requests with the lowest start time in list_out + * (ltime) + */ + if(g_slist_length(list_out) > 0) + ltime = g_slist_append(ltime, g_slist_nth_data(list_out, 0)); + for(iter=g_slist_nth(list_out,1);iter!=NULL;iter=g_slist_next(iter)) { + /* Find all time requests with the lowest start time in list_out */ + guint index_ltime = g_array_index(ltime, guint, 0); + EventsRequest *event_request_ltime = (EventsRequest*)g_slist_nth_data(ltime, 0); + EventsRequest *event_request_list_out = (EventsRequest*)iter->data; + + int comp; + comp = ltt_time_compare(event_request_ltime->start_time, + event_request_list_out->start_time); + if(comp == 0) + ltime = g_slist_append(ltime, event_request_list_out); + else if(comp > 0) { + /* Remove all elements from ltime, and add current */ + while(ltime != NULL) + ltime = g_slist_delete_link(ltime, g_slist_nth(ltime, 0)); + ltime = g_slist_append(ltime, event_request_list_out); + } + } + + /* 1.1.2 Find all position requests with the lowest position in list_out + * (lpos) + */ + if(g_slist_length(list_out) > 0) + lpos = g_slist_append(lpos, g_slist_nth_data(list_out, 0)); + for(iter=g_slist_nth(list_out,1);iter!=NULL;iter=g_slist_next(iter)) { + /* Find all position requests with the lowest position in list_out */ + guint index_lpos = g_array_index(lpos, guint, 0); + EventsRequest *event_request_lpos = (EventsRequest*)g_slist_nth_data(lpos, 0); + EventsRequest *event_request_list_out = (EventsRequest*)iter->data; + + int comp; + if(event_request_lpos->start_position != NULL + && event_request_list_out->start_position != NULL) + { + comp = lttv_traceset_context_pos_pos_compare + (event_request_lpos->start_position, + event_request_list_out->start_position); + } else { + comp = -1; + } + if(comp == 0) + lpos = g_slist_append(lpos, event_request_list_out); + else if(comp > 0) { + /* Remove all elements from lpos, and add current */ + while(lpos != NULL) + lpos = g_slist_delete_link(lpos, g_slist_nth(lpos, 0)); + lpos = g_slist_append(lpos, event_request_list_out); + } + } + + /* 1.1.3 If lpos.start time < ltime */ + { + EventsRequest *event_request_lpos = (EventsRequest*)g_slist_nth_data(lpos, 0); + EventsRequest *event_request_ltime = (EventsRequest*)g_slist_nth_data(ltime, 0); + LttTime lpos_start_time; + + if(event_request_lpos != NULL + && event_request_lpos->start_position != NULL) { + + lpos_start_time = lttv_traceset_context_position_get_time( + event_request_lpos->start_position); + if(ltt_time_compare(lpos_start_time, + event_request_ltime->start_time)<0) { + /* Add lpos to list_in, remove them from list_out */ + + for(iter=lpos;iter!=NULL;iter=g_slist_next(iter)) { + /* Add to list_in */ + EventsRequest *event_request_lpos = + (EventsRequest*)iter->data; + + g_slist_append(list_in, event_request_lpos); + /* Remove from list_out */ + g_slist_remove(list_out, event_request_lpos); + } + } + } else { + /* 1.1.4 (lpos.start time >= ltime) */ + /* Add ltime to list_in, remove them from list_out */ + + for(iter=ltime;iter!=NULL;iter=g_slist_next(iter)) { + /* Add to list_in */ + EventsRequest *event_request_ltime = + (EventsRequest*)iter->data; + + g_slist_append(list_in, event_request_ltime); + /* Remove from list_out */ + g_slist_remove(list_out, event_request_ltime); + } + } + } + g_slist_free(lpos); + g_slist_free(ltime); + } - //call hooks to show each viewer and let them remove hooks - //show_viewer(mw_data); + /* 1.2 Seek */ + { + tfc = lttv_traceset_context_get_current_tfc(tsc); + g_assert(g_slist_length(list_in)>0); + EventsRequest *events_request = g_slist_nth_data(list_in, 0); + + /* 1.2.1 If first request in list_in is a time request */ + if(events_request->start_position == NULL) { + /* - If first req in list_in start time != current time */ + if(tfc != NULL && ltt_time_compare(events_request->start_time, + tfc->timestamp) != 0) + /* - Seek to that time */ + lttv_process_traceset_seek_time(tsc, events_request->start_time); + } else { + /* Else, the first request in list_in is a position request */ + /* If first req in list_in pos != current pos */ + g_assert(events_request->start_position != NULL); + if(lttv_traceset_context_ctx_pos_compare(tsc, + events_request->start_position) != 0) { + /* 1.2.2.1 Seek to that position */ + lttv_process_traceset_seek_position(tsc, events_request->start_position); + } + } + } - // FIXME - // call process trace for each time interval - // Will have to be combined! - g_critical("SIZE time req len : %d", mw_data->current_tab->time_requests->len); - - //g_assert(mw_data->current_tab->time_requests->len <= 1); //FIXME - /* Go through each time request. As they are already sorted by start_time, - * we check with the current event time if processing is needed. */ - for(i=0; i < mw_data->current_tab->time_requests->len; i++) - { - g_critical("RUN i %d", i); - TimeRequest *time_request = - &g_array_index(mw_data->current_tab->time_requests, TimeRequest, i); - LttTime end_time = ltt_time_add( time_request->time_window.start_time, - time_request->time_window.time_width); + /* 1.3 Add hooks and call before request for all list_in members */ + { + GSList *iter = NULL; + + for(iter=list_in;iter!=NULL;iter=g_slist_next(iter)) { + EventsRequest *events_request = (EventsRequest*)iter->data; + /* 1.3.1 If !servicing */ + if(events_request->servicing == FALSE) { + /* - begin request hooks called + * - servicing = TRUE + */ + lttv_hooks_call(events_request->before_request, NULL); + events_request->servicing = TRUE; + } + /* 1.3.2 call before chunk + * 1.3.3 events hooks added + */ + lttv_process_traceset_begin(tsc, events_request->before_chunk_traceset, + events_request->before_chunk_trace, + events_request->before_chunk_tracefile, + events_request->event, + events_request->event_by_id); + } + } + } else { + /* 2. Else, list_in is not empty, we continue a read */ + GSList *iter = NULL; + tfc = lttv_traceset_context_get_current_tfc(tsc); - if(i == 0 || !(ltt_time_compare(time_request->time_window.start_time, ltt_event_time(tsc->e))<0) ) + /* 2.1 For each req of list_out */ + for(iter=list_out;iter!=NULL;iter=g_slist_next(iter)) { + EventsRequest *events_request = (EventsRequest*)iter->data; + + /* if req.start time == current context time + * or req.start position == current position*/ + if( ltt_time_compare(events_request->start_time, + tfc->timestamp) == 0 + || + (events_request->start_position != NULL + && + lttv_traceset_context_ctx_pos_compare(tsc, + events_request->start_position) == 0) + ) { + /* - Add to list_in, remove from list_out */ + g_slist_append(list_in, events_request); + g_slist_remove(list_out, events_request); + + /* - If !servicing */ + if(events_request->servicing == FALSE) { + /* - begin request hooks called + * - servicing = TRUE + */ + lttv_hooks_call(events_request->before_request, NULL); + events_request->servicing = TRUE; + } + /* call before chunk + * events hooks added + */ + lttv_process_traceset_begin(tsc, events_request->before_chunk_traceset, + events_request->before_chunk_trace, + events_request->before_chunk_tracefile, + events_request->event, + events_request->event_by_id); + } + } + } + + /* 3. Find end criterions */ { - /* do it if first request or start_time >= last event's time */ - lttv_process_traceset_seek_time(tsc, time_request->time_window.start_time); - lttv_process_traceset(tsc, end_time, time_request->num_events); + /* 3.1 End time */ + GSList *iter; + + /* 3.1.1 Find lowest end time in list_in */ + g_assert(g_slist_length(list_in)>0); + end_time = ((EventsRequest*)g_slist_nth_data(list_in,0))->end_time; + + for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) { + EventsRequest *events_request = (EventsRequest*)iter->data; + + if(ltt_time_compare(events_request->end_time, + end_time) < 0) + end_time = events_request->end_time; + } + + /* 3.1.2 Find lowest start time in list_out */ + for(iter=list_out;iter!=NULL;iter=g_slist_next(iter)) { + EventsRequest *events_request = (EventsRequest*)iter->data; + + if(ltt_time_compare(events_request->start_time, + end_time) < 0) + end_time = events_request->start_time; + } } - else + { - if(ltt_time_compare(time_request->time_window.start_time, ltt_event_time(tsc->e))<0 - && !(ltt_time_compare(end_time, ltt_event_time(tsc->e))<0)) - { - /* Continue reading from current event */ - lttv_process_traceset(tsc, end_time, time_request->num_events); + /* 3.2 Number of events */ + + /* 3.2.1 Find lowest number of events in list_in */ + GSList *iter; + end_nb_events = ((EventsRequest*)g_slist_nth_data(list_in,0))->num_events; + + for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) { + EventsRequest *events_request = (EventsRequest*)iter->data; + + if(events_request->num_events < end_nb_events) + end_nb_events = events_request->num_events; } - else + + /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as + * num_events */ + + end_nb_events = MIN(CHUNK_NUM_EVENTS, end_nb_events); + } + + { + /* 3.3 End position */ + + /* 3.3.1 Find lowest end position in list_in */ + GSList *iter; + + end_position =((EventsRequest*)g_slist_nth_data(list_in,0))->end_position; + + for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) { + EventsRequest *events_request = (EventsRequest*)iter->data; + + if(events_request->end_position != NULL && end_position != NULL && + lttv_traceset_context_pos_pos_compare(events_request->end_position, + end_position) <0) + end_position = events_request->end_position; + } + } + + { + /* 3.3.2 Find lowest start position in list_out */ + GSList *iter; + + for(iter=list_out;iter!=NULL;iter=g_slist_next(iter)) { + EventsRequest *events_request = (EventsRequest*)iter->data; + + if(events_request->end_position != NULL && end_position != NULL && + lttv_traceset_context_pos_pos_compare(events_request->end_position, + end_position) <0) + end_position = events_request->end_position; + } + } + + { + /* 4. Call process traceset middle */ + count = lttv_process_traceset_middle(tsc, end_time, end_nb_events, end_position); + } + { + /* 5. After process traceset middle */ + tfc = lttv_traceset_context_get_current_tfc(tsc); + + /* - if current context time > traceset.end time */ + if(tfc == NULL || ltt_time_compare(tfc->timestamp, + tsc->time_span.end_time) > 0) { + /* - For each req in list_in */ + GSList *iter = list_in; + + while(iter != NULL) { + + gboolean remove = FALSE; + gboolean free_data = FALSE; + EventsRequest *events_request = (EventsRequest *)iter->data; + + /* - Remove events hooks for req + * - Call end chunk for req + */ + lttv_process_traceset_end(tsc, events_request->after_chunk_traceset, + events_request->after_chunk_trace, + events_request->after_chunk_tracefile, + events_request->event, + events_request->event_by_id); + /* - Call end request for req */ + lttv_hooks_call(events_request->after_request, NULL); + + /* - remove req from list_in */ + /* Destroy the request */ + remove = TRUE; + free_data = TRUE; + + /* Go to next */ + if(remove) + { + GSList *remove_iter = iter; + + iter = g_slist_next(iter); + if(free_data) g_free(remove_iter->data); + list_in = g_slist_remove_link(list_in, remove_iter); + } else { // not remove + iter = g_slist_next(iter); + } + } + } + { - if(ltt_time_compare(time_request->time_window.start_time, end_time) > 0) - { - /* This is a request for a minimum number of events, give - * more events than necessary */ - lttv_process_traceset(tsc, end_time, time_request->num_events); + /* 5.1 For each req in list_in */ + GSList *iter = list_in; + + while(iter != NULL) { + + gboolean remove = FALSE; + gboolean free_data = FALSE; + EventsRequest *events_request = (EventsRequest *)iter->data; + + /* - Remove events hooks for req + * - Call end chunk for req + */ + lttv_process_traceset_end(tsc, events_request->after_chunk_traceset, + events_request->after_chunk_trace, + events_request->after_chunk_tracefile, + events_request->event, + events_request->event_by_id); + + /* - req.num -= count */ + g_assert(events_request->num_events >= count); + events_request->num_events -= count; + + g_assert(tfc != NULL); + /* - if req.num == 0 + * or + * current context time > req.end time + * or + * req.end pos == current pos + * or + * req.stop_flag == TRUE + */ + if( events_request->num_events == 0 + || + events_request->stop_flag == TRUE + || + ltt_time_compare(tfc->timestamp, + events_request->end_time) > 0 + || + (events_request->start_position != NULL + && + lttv_traceset_context_ctx_pos_compare(tsc, + events_request->start_position) != 0) + + ) { + /* - Call end request for req + * - remove req from list_in */ + lttv_hooks_call(events_request->after_request, NULL); + /* - remove req from list_in */ + /* Destroy the request */ + remove = TRUE; + free_data = TRUE; + } + + /* Go to next */ + if(remove) + { + GSList *remove_iter = iter; + + iter = g_slist_next(iter); + if(free_data) g_free(remove_iter->data); + list_in = g_slist_remove_link(list_in, remove_iter); + } else { // not remove + iter = g_slist_next(iter); + } } } } + } + + /* B. When interrupted between chunks */ + + { + GSList *iter = list_in; + + /* 1. for each request in list_in */ + while(iter != NULL) { + + gboolean remove = FALSE; + gboolean free_data = FALSE; + EventsRequest *events_request = (EventsRequest *)iter->data; + + /* 1.1. Use current postition as start position */ + g_free(events_request->start_position); + lttv_traceset_context_position_save(tsc, events_request->start_position); + + /* 1.2. Remove start time */ + events_request->start_time.tv_sec = G_MAXUINT; + events_request->start_time.tv_nsec = G_MAXUINT; + + /* 1.3. Move from list_in to list_out */ + remove = TRUE; + free_data = FALSE; + list_out = g_slist_append(list_out, events_request); + + /* Go to next */ + if(remove) + { + GSList *remove_iter = iter; + + iter = g_slist_next(iter); + if(free_data) g_free(remove_iter->data); + list_in = g_slist_remove_link(list_in, remove_iter); + } else { // not remove + iter = g_slist_next(iter); + } + } + - /* Call the end of process_traceset hook */ - lttv_hooks_add(tmp_hooks, - time_request->after_hook, - time_request->after_hook_data); - lttv_hooks_call(tmp_hooks, time_request); - lttv_hooks_remove(tmp_hooks, time_request->after_hook); } - - /* Free the time requests */ - g_array_free(mw_data->current_tab->time_requests, TRUE); - mw_data->current_tab->time_requests = - g_array_new(FALSE, FALSE, sizeof(TimeRequest)); - - mw_data->current_tab->time_request_pending = FALSE; - - lttv_hooks_destroy(tmp_hooks); - + //set the cursor back to normal gdk_window_set_cursor(win, NULL); + + + g_assert(g_slist_length(list_in) == 0); + if( g_slist_length(list_out) == 0 ) { + /* Put tab's request pending flag back to normal */ + tab->events_request_pending = FALSE; + return FALSE; /* Remove the idle function */ + } + return TRUE; /* Leave the idle function */ } + /* add_trace_into_traceset_selector, each instance of a viewer has an associated * selector (filter), when a trace is added into traceset, the selector should * reflect the change. The function is used to update the selector @@ -635,12 +1009,12 @@ void add_trace(GtkWidget * widget, gpointer user_data) lttv_traceset_number(mw_data->current_tab->traceset_info->traceset) == 1 || ltt_time_compare(mw_data->current_tab->current_time, LTTV_TRACESET_CONTEXT(mw_data->current_tab->traceset_info-> - traceset_context)->Time_Span->startTime)<0) + traceset_context)->time_span.start_time)<0) { /* Set initial time if this is the first trace in the traceset */ mw_data->current_tab->current_time = LTTV_TRACESET_CONTEXT(mw_data->current_tab->traceset_info-> - traceset_context)->Time_Span->startTime; + traceset_context)->time_span.start_time; mw_data->current_tab->time_window.start_time = mw_data->current_tab->current_time; mw_data->current_tab->time_window.time_width.tv_sec = @@ -650,7 +1024,7 @@ void add_trace(GtkWidget * widget, gpointer user_data) /* Call the updatetraceset hooks */ - SetTraceset(mw_data, (gpointer)traceset); + SetTraceset(mw_data->current_tab, traceset); // in expose now call_pending_read_hooks(mw_data); //lttvwindow_report_current_time(mw_data,&(mw_data->current_tab->current_time)); @@ -842,23 +1216,25 @@ void zoom(GtkWidget * widget, double size) TimeWindow new_time_window; LttTime current_time, time_delta, time_s, time_e, time_tmp; MainWindow * mw_data = get_window_data_struct(widget); + Tab *tab = mw_data->current_tab; + LttvTracesetContext *tsc = + LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context); if(size == 1) return; - time_span = LTTV_TRACESET_CONTEXT(mw_data->current_tab-> - traceset_info->traceset_context)->Time_Span; - new_time_window = mw_data->current_tab->time_window; - current_time = mw_data->current_tab->current_time; + time_span = &tsc->time_span; + new_time_window = tab->time_window; + current_time = tab->current_time; - time_delta = ltt_time_sub(time_span->endTime,time_span->startTime); + time_delta = ltt_time_sub(time_span->end_time,time_span->start_time); if(size == 0){ - new_time_window.start_time = time_span->startTime; + new_time_window.start_time = time_span->start_time; new_time_window.time_width = time_delta; }else{ new_time_window.time_width = ltt_time_div(new_time_window.time_width, size); if(ltt_time_compare(new_time_window.time_width,time_delta) > 0) { /* Case where zoom out is bigger than trace length */ - new_time_window.start_time = time_span->startTime; + new_time_window.start_time = time_span->start_time; new_time_window.time_width = time_delta; } else @@ -868,18 +1244,18 @@ void zoom(GtkWidget * widget, double size) new_time_window.start_time = ltt_time_sub(current_time, ltt_time_div(new_time_window.time_width, 2.0)); /* If on borders, don't fall off */ - if(ltt_time_compare(new_time_window.start_time, time_span->startTime) <0) + if(ltt_time_compare(new_time_window.start_time, time_span->start_time) <0) { - new_time_window.start_time = time_span->startTime; + new_time_window.start_time = time_span->start_time; } else { if(ltt_time_compare( ltt_time_add(new_time_window.start_time, new_time_window.time_width), - time_span->endTime) > 0) + time_span->end_time) > 0) { new_time_window.start_time = - ltt_time_sub(time_span->endTime, new_time_window.time_width); + ltt_time_sub(time_span->end_time, new_time_window.time_width); } } @@ -907,9 +1283,9 @@ void zoom(GtkWidget * widget, double size) //call_pending_read_hooks(mw_data); //lttvwindow_report_current_time(mw_data,&(mw_data->current_tab->current_time)); - set_time_window(mw_data, &new_time_window); + set_time_window(tab, &new_time_window); // in expose now call_pending_read_hooks(mw_data); - gtk_multi_vpaned_set_adjust(mw_data->current_tab->multi_vpaned, &new_time_window, FALSE); + gtk_multi_vpaned_set_adjust(tab->multi_vpaned, &new_time_window, FALSE); } void zoom_in(GtkWidget * widget, gpointer user_data) @@ -1476,17 +1852,30 @@ on_button_delete_viewer_clicked (GtkButton *button, } void -on_MWindow_destroy (GtkObject *object, +on_MWindow_destroy (GtkWidget *widget, gpointer user_data) { - MainWindow *Main_Window = get_window_data_struct((GtkWidget*)object); - GtkWidget *widget; - Tab *tab = Main_Window->tab; + MainWindow *main_window = get_window_data_struct(widget); + LttvIAttribute *attributes = main_window->attributes; + LttvAttributeValue value; - g_printf("There are : %d windows\n",g_slist_length(g_main_window_list)); + //This is unnecessary, since widgets will be destroyed + //by the main window widget anyway. + //remove_all_menu_toolbar_constructors(main_window, NULL); + + g_assert(lttv_iattribute_find_by_path(attributes, + "viewers/menu", LTTV_POINTER, &value)); + lttv_menus_destroy((LttvMenus*)*(value.v_pointer)); + + g_assert(lttv_iattribute_find_by_path(attributes, + "viewers/toolbar", LTTV_POINTER, &value)); + lttv_toolbars_destroy((LttvToolbars*)*(value.v_pointer)); + + g_object_unref(main_window->attributes); + g_main_window_list = g_slist_remove(g_main_window_list, main_window); - g_win_count--; - if(g_win_count == 0) + g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list)); + if(g_slist_length(g_main_window_list) == 0) gtk_main_quit (); } @@ -1871,7 +2260,7 @@ char * get_selection(char ** loaded_module_name, int nb_module, } -/* Insert or remove all menu entry and tool buttons into this main window +/* Insert all menu entry and tool buttons into this main window * for modules. * */ @@ -1887,19 +2276,19 @@ void add_all_menu_toolbar_constructors(MainWindow * mw, gpointer user_data) LttvToolbarClosure *toolbar_item; LttvAttributeValue value; LttvIAttribute *global_attributes = LTTV_IATTRIBUTE(lttv_global_attributes()); - LttvIAttribute *attributes = LTTV_IATTRIBUTES(mw->attributes); + LttvIAttribute *attributes = mw->attributes; GtkWidget * tool_menu_title_menu, *new_widget, *pixmap; g_assert(lttv_iattribute_find_by_path(global_attributes, "viewers/menu", LTTV_POINTER, &value)); if(*(value.v_pointer) == NULL) - (LttvMenus*)*(value.v_pointer) = lttv_menus_new(); + *(value.v_pointer) = lttv_menus_new(); global_menu = (LttvMenus*)*(value.v_pointer); g_assert(lttv_iattribute_find_by_path(attributes, "viewers/menu", LTTV_POINTER, &value)); if(*(value.v_pointer) == NULL) - (LttvMenus*)*(value.v_pointer) = lttv_menus_new(); + *(value.v_pointer) = lttv_menus_new(); instance_menu = (LttvMenus*)*(value.v_pointer); @@ -1907,13 +2296,13 @@ void add_all_menu_toolbar_constructors(MainWindow * mw, gpointer user_data) g_assert(lttv_iattribute_find_by_path(global_attributes, "viewers/toolbar", LTTV_POINTER, &value)); if(*(value.v_pointer) == NULL) - (LttvToolbars*)*(value.v_pointer) = lttv_toolbars_new(); + *(value.v_pointer) = lttv_toolbars_new(); global_toolbar = (LttvToolbars*)*(value.v_pointer); g_assert(lttv_iattribute_find_by_path(attributes, "viewers/toolbar", LTTV_POINTER, &value)); if(*(value.v_pointer) == NULL) - (LttvToolbars*)*(value.v_pointer) = lttv_toolbars_new(); + *(value.v_pointer) = lttv_toolbars_new(); instance_toolbar = (LttvToolbars*)*(value.v_pointer); /* Add missing menu entries to window instance */ @@ -1924,7 +2313,7 @@ void add_all_menu_toolbar_constructors(MainWindow * mw, gpointer user_data) constructor = menu_item->con; tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu"); new_widget = - gtk_menu_item_new_with_mnemonic (menu_item->menuText); + gtk_menu_item_new_with_mnemonic (menu_item->menu_text); gtk_container_add (GTK_CONTAINER (tool_menu_title_menu), new_widget); g_signal_connect ((gpointer) new_widget, "activate", @@ -2005,15 +2394,18 @@ void construct_main_window(MainWindow * parent) g_assert(lttv_iattribute_find_by_path(attributes, "viewers/menu", LTTV_POINTER, &value)); - (LttvMenus*)*(value.v_pointer) = lttv_menus_new(); + *(value.v_pointer) = lttv_menus_new(); - g_assert(lttv_iattribute_find_by_path(attributes_global, + g_assert(lttv_iattribute_find_by_path(attributes, "viewers/toolbar", LTTV_POINTER, &value)); - (LttvToolbars*)*(value.v_pointer) = lttv_toolbars_new(); + *(value.v_pointer) = lttv_toolbars_new(); add_all_menu_toolbar_constructors(new_m_window, NULL); - g_object_set_data(G_OBJECT(new_window), "mainWindow", (gpointer)new_m_window); + g_object_set_data_full(G_OBJECT(new_window), + "main_window_data", + (gpointer)new_m_window, + (GDestroyNotify)g_free); //create a default tab notebook = (GtkNotebook *)lookup_widget(new_m_window->mwindow, "MNotebook"); if(notebook == NULL){ @@ -2024,13 +2416,7 @@ void construct_main_window(MainWindow * parent) //Use "Traceset" as the label for the default tab create_tab(parent, new_m_window, notebook, "Traceset"); - g_object_set_data_full( - G_OBJECT(new_m_window->mwindow), - "Main_Window_Data", - new_m_window, - (GDestroyNotify)main_window_free); - - g_win_count++; + g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list)); } @@ -2044,7 +2430,11 @@ void tab_destructor(Tab * tab_instance) LttvTrace * trace; if(tab_instance->attributes) - g_object_unref(tab_instance->attributes); + g_object_unref(tab_instance->attributes); + + if(tab_instance->interrupted_state) + g_object_unref(tab_instance->interrupted_state); + if(tab_instance->mw->tab == tab_instance){ tab_instance->mw->tab = tab_instance->next; @@ -2079,7 +2469,10 @@ void tab_destructor(Tab * tab_instance) } } lttv_traceset_destroy(tab_instance->traceset_info->traceset); - g_array_free(tab_instance->time_requests, TRUE); + /* Remove the idle events requests processing function of the tab */ + g_idle_remove_by_data(tab_instance); + + g_slist_free(tab_instance->events_requests); g_free(tab_instance->traceset_info); g_free(tab_instance); } @@ -2113,8 +2506,7 @@ void * create_tab(MainWindow * parent, MainWindow* current_window, if(parent){ if(parent->current_tab){ tmp_tab->traceset_info->traceset = - lttv_traceset_new(); - //FIXME lttv_traceset_copy(parent->current_tab->traceset_info->traceset); + lttv_traceset_copy(parent->current_tab->traceset_info->traceset); }else{ tmp_tab->traceset_info->traceset = lttv_traceset_new(); } @@ -2122,8 +2514,7 @@ void * create_tab(MainWindow * parent, MainWindow* current_window, }else{ /* Initial window */ if(mw_data->current_tab){ tmp_tab->traceset_info->traceset = - lttv_traceset_new(); - //FIXME lttv_traceset_copy(mw_data->current_tab->traceset_info->traceset); + lttv_traceset_copy(mw_data->current_tab->traceset_info->traceset); }else{ tmp_tab->traceset_info->traceset = lttv_traceset_new(); /* Add the command line trace */ @@ -2132,7 +2523,15 @@ void * create_tab(MainWindow * parent, MainWindow* current_window, } } } - + +//FIXME : this is g_debug level + lttv_attribute_write_xml( + lttv_traceset_attribute(tmp_tab->traceset_info->traceset), + stdout, + 0, 4); + fflush(stdout); + + //FIXME copy not implemented in lower level tmp_tab->traceset_info->traceset_context = g_object_new(LTTV_TRACESET_STATS_TYPE, NULL); @@ -2155,26 +2554,27 @@ void * create_tab(MainWindow * parent, MainWindow* current_window, // to be able to modify a traceset on the fly. // get_traceset_time_span(mw_data,&tmp_tab->traceStartTime, &tmp_tab->traceEndTime); tmp_tab->time_window.start_time = - LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->startTime; + LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->time_span.start_time; if(DEFAULT_TIME_WIDTH_S < - LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->endTime.tv_sec) + LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->time_span.end_time.tv_sec) tmp_time.tv_sec = DEFAULT_TIME_WIDTH_S; else tmp_time.tv_sec = - LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->endTime.tv_sec; + LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->time_span.end_time.tv_sec; tmp_time.tv_nsec = 0; tmp_tab->time_window.time_width = tmp_time ; tmp_tab->current_time.tv_sec = - LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->startTime.tv_sec; + LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->time_span.start_time.tv_sec; tmp_tab->current_time.tv_nsec = - LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->startTime.tv_nsec; + LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->time_span.start_time.tv_nsec; } /* Become the current tab */ mw_data->current_tab = tmp_tab; tmp_tab->attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL)); + tmp_tab->interrupted_state = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); tmp_tab->multi_vpaned = (GtkMultiVPaned*)gtk_multi_vpaned_new(); - tmp_tab->multi_vpaned->mw = mw_data; + tmp_tab->multi_vpaned->tab = mw_data->current_tab; gtk_widget_show((GtkWidget*)tmp_tab->multi_vpaned); tmp_tab->next = NULL; tmp_tab->mw = mw_data; @@ -2182,8 +2582,9 @@ void * create_tab(MainWindow * parent, MainWindow* current_window, tmp_tab->label = gtk_label_new (label); gtk_widget_show (tmp_tab->label); - tmp_tab->time_requests = g_array_new(FALSE, FALSE, sizeof(TimeRequest)); - tmp_tab->time_request_pending = FALSE; + /* Start with empty events requests list */ + tmp_tab->events_requests = NULL; + tmp_tab->events_request_pending = FALSE; g_object_set_data_full( G_OBJECT(tmp_tab->multi_vpaned), @@ -2233,11 +2634,15 @@ void show_viewer(MainWindow *main_win) } - -gboolean execute_time_requests(MainWindow * mw) +/* + * execute_events_requests + * + * Idle function that executes the pending requests for a tab. + * + * @return return value : TRUE : keep the idle function, FALSE : remove it. + */ +gboolean execute_events_requests(Tab *tab) { - call_pending_read_hooks(mw); - - return FALSE; // automatically removed from the list of event sources + return ( lttvwindow_process_pending_requests(tab) ); }