From 501e4e70320aeb56090ada4447958db1c2ed6616 Mon Sep 17 00:00:00 2001 From: compudj Date: Mon, 14 Jun 2004 20:01:13 +0000 Subject: [PATCH] viewer -> lttvwindow name change git-svn-id: http://ltt.polymtl.ca/svn@591 04897980-b3bd-0310-b5e0-8ef037075253 --- .../gui/lttvwindow/lttvwindow/Makefile.am | 4 +- .../gui/lttvwindow/lttvwindow/callbacks.c | 616 ++++++++++--- .../lttvwindow/lttvwindow/gtkmultivpaned.c | 20 +- .../gui/lttvwindow/lttvwindow/lttvwindow.c | 866 ++++++++++++++++++ .../gui/lttvwindow/lttvwindow/lttvwindow.h | 718 +++++++++++++++ .../modules/gui/lttvwindow/lttvwindow/menu.h | 6 +- .../gui/lttvwindow/lttvwindow/toolbar.h | 2 +- 7 files changed, 2089 insertions(+), 143 deletions(-) create mode 100644 ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.c create mode 100644 ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h diff --git a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/Makefile.am b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/Makefile.am index 54407a99..e4253406 100644 --- a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/Makefile.am +++ b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/Makefile.am @@ -23,7 +23,7 @@ liblttvwindow_la_SOURCES = \ menu.c\ gtkdirsel.c\ gtkmultivpaned.c\ - viewer.c \ + lttvwindow.c \ init_module.c \ support.c \ interface.c \ @@ -39,7 +39,7 @@ lttvwindowinclude_HEADERS = \ common.h\ gtkdirsel.h\ gtkmultivpaned.h\ - viewer.h\ + lttvwindow.h\ lttvfilter.h\ mainwindow.h\ menu.h\ 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 f42e5ea2..4ffac2db 100644 --- a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c +++ b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include @@ -76,7 +76,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); +static gboolean lttvwindow_process_pending_requests(Tab *tab); unsigned get_max_event_number(MainWindow * mw_data); enum { @@ -162,20 +162,20 @@ insert_viewer_wrap(GtkWidget *menuitem, gpointer user_data) /* internal functions */ -void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor) +static 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); @@ -375,127 +375,474 @@ unsigned get_max_event_number(MainWindow * mw_data) } -/* 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; + 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; + /* (Xang Xiu) It makes the expose works.. MD:? */ + if(tab == NULL) + return FALSE; - if(mw_data->current_tab->time_requests->len == 0) - return; + /* There is no events requests pending : we should never have been called! */ + g_assert(g_slist_length(events_requests) != 0); - LttvHooks *tmp_hooks = lttv_hooks_new(); - - 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_data->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_request)); + + /* Events processing algorithm implementation */ + /* A. Servicing loop */ + while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0) + && !gtk_events_pending() ) { + + /* 1. If list_in is empty (need a seek) */ + if( g_slist_length(list_in) == 0 ) { - g_array_sort(mw_data->current_tab->time_requests, - (GCompareFunc)compare_time_request); + /* list in is empty, need a seek */ + { + /* 1.1 Add requests to list_in */ + GArray *ltime = g_array_new(FALSE, FALSE, sizeof(guint)); + GArray *lpos = g_array_new(FALSE, FALSE, sizeof(guint)); + guint i; + + /* 1.1.1 Find all time requests with the lowest start time in list_out + * (ltime) + */ + if(list_out->len > 0) + g_array_append_val(ltime, 0); + for(i=1;ilen;i++) { + /* 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 = &g_array_index(list_out, + EventsRequest, + index_ltime); + EventsRequest *event_request_list_out = &g_array_index(list_out, + EventsRequest, + i); + int comp; + comp = ltt_time_compare(event_request_ltime->start_time, + event_request_list_out->start_time); + if(comp == 0) + g_array_append_val(ltime, i); + else if(comp > 0) { + /* Remove all elements from ltime, and add current */ + g_array_remove_range(ltime, 0, ltime->len); + g_array_append_val(ltime, i); + + } + } + + /* 1.1.2 Find all position requests with the lowest position in list_out + * (lpos) + */ + if(list_out->len > 0) + g_array_append(lpos, 0); + for(i=1;ilen;i++) { + /* Find all position requests with the lowest position in list_out */ + guint index_lpos = g_array_index(lpos, guint, 0); + EventsRequest *event_request_lpos = &g_array_index(lpos, + EventsRequest, + index_lpos); + EventsRequest *event_request_list_out = &g_array_index(list_out, + EventsRequest, + i); + int comp; + comp = lttv_traceset_context_pos_pos_compare + (event_request_pos->start_position, + event_request_list_out->start_position); + if(comp == 0) + g_array_append_val(lpos, i); + else if(comp > 0) { + /* Remove all elements from lpos, and add current */ + g_array_remove_range(lpos, 0, lpos->len); + g_array_append_val(lpos, i); + } + } + + /* 1.1.3 If lpos.start time < ltime */ + { + guint i; + EventsRequest *event_request_lpos = &g_array_index(lpos, 0); + EventsRequest *event_request_ltime = &g_array_index(ltime,0); + LttTime lpos_start_time = + lttv_traceset_context_position_get_time(event_request_lpos); + + if(ltt_time_compare(lpos_start_time, + event_request_ltime->start_time)<0) { + /* Add lpos to list_in, remove them from list_out */ + + for(i=0;ilen;i++) { + /* Add to list_in */ + guint index_lpos = g_array_index(lpos, guint, i); + EventsRequest *event_request_lpos = + &g_array_index(lpos,index_lpos); + + g_array_append_val(list_in, *event_request_lpos); + + } + + for(i=0;ilen;i++) { + /* Remove from list_out */ + guint index_lpos = g_array_index(lpos, guint, i); + + g_array_remove_index_fast(list_out, index_lpos); + } + + } else { + /* 1.1.4 (lpos.start time >= ltime) */ + /* Add ltime to list_in, remove them from list_out */ + + for(i=0;ilen;i++) { + /* Add to list_in */ + guint index_ltime = g_array_index(ltime, guint, i); + EventsRequest *event_request_ltime = + &g_array_index(ltime,index_ltime); + + g_array_append_val(list_in, *event_request_ltime); + } + + for(i=0;ilen;i++) { + /* Remove from list_out */ + guint index_ltime = g_array_index(ltime, guint, i); + + g_array_remove_index_fast(list_out, index_ltime); + } + } + } + g_array_free(lpos, TRUE); + g_array_free(ltime, TRUE); + } + /* 1.2 Seek */ + { + EventsRequest *events_request = &g_array_index(list_in, + EventsRequest, + 0); + + /* 1.2.1 If first request in list_in is a time request */ + if(events_request->start_position == NULL) { + /* 1.2.1.1 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 */ + /* 1.2.2.1 Seek to that position */ + lttv_process_traceset_seek_position(tsc, events_request->start_position); + } + } - //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); + /* 1.3 Call begin for all list_in members */ + { + guint i; + + for(i=0;ilen;i++) { + EventsRequest *events_request = &g_array_index(list_in, + EventsRequest, + i); + /* (1.3.1 begin hooks called) */ + /* (1.3.2 middle hooks added) */ + lttv_process_traceset_begin(tsc, events_request->before_traceset, + events_request->before_trace, + events_request->before_tracefile, + events_request->event, + events_request->event_by_id); + } + } + } else { + /* 2. Else, list_in is not empty, we continue a read */ + guint i; + tfc = lttv_traceset_context_get_current_tfc(tsc); + + /* 2.1 For each req of list_out */ + for(i=0;ilen;i++) { + EventsRequest *events_request = &g_array_index(list_out, + EventsRequest, + i); + if(ltt_time_compare(events_request->start_time, + tfc->timestamp) == 0) { + /* if req.start time == current context time */ + /* Call Begin */ + lttv_process_traceset_begin(tsc, events_request->before_traceset, + events_request->before_trace, + events_request->before_tracefile, + events_request->event, + events_request->event_by_id); + + + /* Add to list_in */ + g_array_append_val(list_in, *events_request); + } else if(events_request->start_position != NULL && + lttv_traceset_context_ctx_pos_compare(tsc, + events_request->start_position) == 0) { + /* if req.start position == current position */ + /* Call Begin */ + lttv_process_traceset_begin(tsc, events_request->before_traceset, + events_request->before_trace, + events_request->before_tracefile, + events_request->event, + events_request->event_by_id); + - //call hooks to show each viewer and let them remove hooks - //show_viewer(mw_data); + /* Add to list_in */ + g_array_append_val(list_in, *events_request); - // 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); + } + + } - if(i == 0 || !(ltt_time_compare(time_request->time_window.start_time, ltt_event_time(tsc->e))<0) ) + + for(i=0;ilen;i++) { + EventsRequest *events_request = &g_array_index(list_out, + EventsRequest, + i); + if(ltt_time_compare(events_request->start_time, + tfc->timestamp) == 0) { + /* if req.start time == current context time */ + /* Remove from list_out */ + g_array_remove_index_fast(list_out, i); + } else if(events_request->start_position != NULL && + lttv_traceset_context_ctx_pos_compare(tsc, + events_request->start_position) == 0) { + /* if req.start position == current position */ + /* Remove from list_out */ + g_array_remove_index_fast(list_out, i); + + } + } + } + + + + /* 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 */ + guint i; + + /* 3.1.1 Find lowest end time in list_in */ + end_time = g_array_index(list_in, EventsRequest,0).end_time; + + for(i=1;ilen;i++) { + EventsRequest *events_request = &g_array_index(list_in, + EventsRequest, + i); + 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(i=0;ilen;i++) { + EventsRequest *events_request = &g_array_index(list_out, + EventsRequest, + i); + 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 */ + guint i; + end_nb_events = g_array_index(list_in, EventsRequest, 0).num_events; + + for(i=1;ilen;i++) { + EventsRequest *events_request = &g_array_index(list_in, + EventsRequest, + i); + if(events_request->num_events < end_nb_events) + end_nb_events = events_request->num_events; } - else + } + + { + /* 3.3 End position */ + + /* 3.3.1 Find lowest end position in list_in */ + guint i; + + end_position = g_array_index(list_in, EventsRequest, 0).end_position; + + for(i=1;ilen;i++) { + EventsRequest *events_request = &g_array_index(list_in, + EventsRequest, + i); + + if(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 */ + guint i; + + for(i=0;ilen;i++) { + EventsRequest *events_request = &g_array_index(list_out, + EventsRequest, + i); + + if(lttv_traceset_context_pos_pos_compare(events_request->end_position, + end_position) <0) + end_position = events_request->end_position; + } + } + + + } + + /* B. When interrupted */ + + /* 1. for each request in list_in */ + { + GSList *iter = 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 = { G_MAXUINT, G_MAXUINT }; + + /* 1.3. Call after_traceset */ + /* 1.4. Remove event hooks */ + lttv_process_traceset_end(tsc, events_request->after_traceset, + events_request->after_trace, + events_request->after_tracefile, + events_request->event, + events_request->event_by_id); + + /* 1.5. Put it back in list_out */ + remove = TRUE; + free_data = FALSE; + list_out = g_slist_append(list_out, events_request); + + + /* Go to next */ + if(remove) { - 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); - } + 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); + + } + + /* 2. Save current state into saved_state. */ + { + /* 2.1 Free old saved state. */ + //FIXME : free will need to be able to remove state for a traceset + //with changed traces! + //FIXME lttv_state_state_saved_free( , tab->interrupted_state); + + /* 2.2 save current state. */ + //FIXME + //lttv_state_save( ,tab->interrupted_state); + } - - /* 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); + + + + if( g_slist_length(list_in) == 0 && g_slist_length(list_out) == 0 ) { + /* Put tab's request pending flag back to normal */ + tab->time_request_pending = FALSE; + return FALSE; /* Remove the idle function */ + } + + return TRUE; /* Leave the idle function */ + } +#ifdef TESTCODE + GSList *iter = list_in; + + /* 1. for each request in list_in */ + while(iter != NULL) { + + gboolean remove = FALSE; + gboolean free_data = FALSE; + + + + /* 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); + } + } +#endif //TESTCODE + + /* 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 @@ -635,12 +982,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 = @@ -842,23 +1189,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 +1217,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 +1256,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) @@ -1493,7 +1842,7 @@ on_MWindow_destroy (GtkObject *object, "viewers/menu", LTTV_POINTER, &value)); lttv_menus_destroy((LttvMenus*)*(value.v_pointer)); - g_assert(lttv_iattribute_find_by_path(attributes_global, + g_assert(lttv_iattribute_find_by_path(attributes, "viewers/toolbar", LTTV_POINTER, &value)); lttv_toolbars_destroy((LttvToolbars*)*(value.v_pointer)); @@ -1908,19 +2257,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); @@ -1928,13 +2277,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 */ @@ -1945,7 +2294,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", @@ -2026,11 +2375,11 @@ 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); @@ -2066,7 +2415,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; @@ -2101,7 +2454,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); } @@ -2177,26 +2533,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; @@ -2204,8 +2561,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), @@ -2255,11 +2613,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) ); } diff --git a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/gtkmultivpaned.c b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/gtkmultivpaned.c index 1762798c..24a39b4f 100644 --- a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/gtkmultivpaned.c +++ b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/gtkmultivpaned.c @@ -21,7 +21,7 @@ #include //#include "gtkintl.h" #include -#include +#include static void gtk_multi_vpaned_class_init (GtkMultiVPanedClass *klass); static void gtk_multi_vpaned_init (GtkMultiVPaned *multi_vpaned); @@ -170,14 +170,14 @@ void gtk_multi_vpaned_set_focus (GtkWidget * widget, GtkPaned* paned) void gtk_multi_vpaned_set_adjust(GtkMultiVPaned * multi_vpaned, const TimeWindow *time_window, gboolean first_time) { - //TimeWindow time_window = multi_vpaned->mw->current_tab->time_window; TimeInterval *time_span; double len, start; + LttvTracesetContext *tsc = + LTTV_TRACESET_CONTEXT(multi_vpaned->tab->traceset_info->traceset_context); if(first_time){ - time_span = <TV_TRACESET_CONTEXT(multi_vpaned->mw->current_tab-> - traceset_info->traceset_context)->time_span ; + time_span = &tsc->time_span ; multi_vpaned->hadjust->lower = ltt_time_to_double(time_span->start_time) * NANOSECONDS_PER_SECOND; @@ -231,7 +231,7 @@ void gtk_multi_vpaned_widget_add(GtkMultiVPaned * multi_vpaned, GtkWidget * widg gtk_widget_show(multi_vpaned->hscrollbar); multi_vpaned->hadjust = gtk_range_get_adjustment(GTK_RANGE(multi_vpaned->hscrollbar)); - gtk_multi_vpaned_set_adjust(multi_vpaned, &multi_vpaned->mw->current_tab->time_window, TRUE); + gtk_multi_vpaned_set_adjust(multi_vpaned, &multi_vpaned->tab->time_window, TRUE); gtk_range_set_update_policy (GTK_RANGE(multi_vpaned->hscrollbar), GTK_UPDATE_CONTINUOUS); @@ -416,11 +416,12 @@ void gtk_multi_vpaned_scroll_value_changed(GtkAdjustment *adjust, gpointer multi GtkMultiVPaned * multi_vpaned = (GtkMultiVPaned*)multi_vpaned_arg; gdouble value = gtk_adjustment_get_value(adjust); gdouble upper, lower, ratio; + LttvTracesetContext * tsc = + LTTV_TRACESET_CONTEXT(multi_vpaned->tab->traceset_info->traceset_context); - time_window = multi_vpaned->mw->current_tab->time_window; + time_window = multi_vpaned->tab->time_window; - time_span = <TV_TRACESET_CONTEXT(multi_vpaned->mw->current_tab->traceset_info-> - traceset_context)->time_span ; + time_span = &tsc->time_span ; lower = multi_vpaned->hadjust->lower; upper = multi_vpaned->hadjust->upper; ratio = (value - lower) / (upper - lower); @@ -435,8 +436,7 @@ void gtk_multi_vpaned_scroll_value_changed(GtkAdjustment *adjust, gpointer multi if(ltt_time_compare(time,time_window.time_width) < 0){ time_window.time_width = time; } - set_time_window(multi_vpaned->mw, &time_window); - // done in expose now call_pending_read_hooks(multi_vpaned->mw); + set_time_window(multi_vpaned->tab, &time_window); } diff --git a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.c b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.c new file mode 100644 index 00000000..1733c347 --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.c @@ -0,0 +1,866 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 XangXiu Yang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +/*! \file lttvwindow.c + * \brief API used by the graphical viewers to interact with their tab. + * + * Main window (gui module) is the place to contain and display viewers. + * Viewers (lttv plugins) interact with tab and main window through this API + * and events sent by gtk. + * This header file should be included in each graphic module. + * This library is used by graphical modules to interact with their tab and + * main window. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // for execute_events_requests +#include + + +/** + * Internal function parts + */ + +extern GSList * g_main_window_list; + +/** + * Function to set/update traceset for the viewers + * @param tab viewer's tab + * @param traceset traceset of the main window. + * return value : + * -1 : error + * 0 : traceset updated + * 1 : no traceset hooks to update; not an error. + */ + +int SetTraceset(Tab * tab, gpointer traceset) +{ + LttvHooks * tmp; + LttvAttributeValue value; + + if( lttv_iattribute_find_by_path(tab->attributes, + "hooks/updatetraceset", LTTV_POINTER, &value) != 0) + return -1; + + tmp = (LttvHooks*)*(value.v_pointer); + if(tmp == NULL) return 1; + + + lttv_hooks_call(tmp,traceset); + + return 0; +} + + +/** + * Function to set/update filter for the viewers + * @param tab viewer's tab + * @param filter filter of the main window. + * return value : + * -1 : error + * 0 : filters updated + * 1 : no filter hooks to update; not an error. + */ + +int SetFilter(Tab * tab, gpointer filter) +{ + LttvHooks * tmp; + LttvAttributeValue value; + + if(lttv_iattribute_find_by_path(tab->attributes, + "hooks/updatefilter", LTTV_POINTER, &value) != 0) + return -1; + + tmp = (LttvHooks*)*(value.v_pointer); + + if(tmp == NULL) return 1; + lttv_hooks_call(tmp,filter); + + return 0; +} + +/** + * Function to redraw each viewer belonging to the current tab + * @param tab viewer's tab + */ + +void update_traceset(Tab *tab) +{ + LttvAttributeValue value; + LttvHooks * tmp; + g_assert(lttv_iattribute_find_by_path(tab->attributes, + "hooks/updatetraceset", LTTV_POINTER, &value)); + tmp = (LttvHooks*)*(value.v_pointer); + if(tmp == NULL) return; + lttv_hooks_call(tmp, NULL); +} + +void set_time_window_adjustment(Tab *tab, const TimeWindow* new_time_window) +{ + gtk_multi_vpaned_set_adjust(tab->multi_vpaned, new_time_window, FALSE); +} + + +void set_time_window(Tab *tab, const TimeWindow *time_window) +{ + LttvAttributeValue value; + LttvHooks * tmp; + + TimeWindowNotifyData time_window_notify_data; + TimeWindow old_time_window = tab->time_window; + time_window_notify_data.old_time_window = &old_time_window; + tab->time_window = *time_window; + time_window_notify_data.new_time_window = + &(tab->time_window); + + g_assert(lttv_iattribute_find_by_path(tab->attributes, + "hooks/updatetimewindow", LTTV_POINTER, &value)); + tmp = (LttvHooks*)*(value.v_pointer); + if(tmp == NULL) return; + lttv_hooks_call(tmp, &time_window_notify_data); + + +} + +void add_toolbar_constructor(MainWindow *mw, LttvToolbarClosure *toolbar_c) +{ + LttvIAttribute *attributes = mw->attributes; + LttvAttributeValue value; + LttvToolbars * instance_toolbar; + lttvwindow_viewer_constructor constructor; + GtkWidget * tool_menu_title_menu, *new_widget, *pixmap; + GdkPixbuf *pixbuf; + + g_assert(lttv_iattribute_find_by_path(attributes, + "viewers/toolbar", LTTV_POINTER, &value)); + if(*(value.v_pointer) == NULL) + *(value.v_pointer) = lttv_toolbars_new(); + instance_toolbar = (LttvToolbars*)*(value.v_pointer); + + constructor = toolbar_c->con; + tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1"); + pixbuf = gdk_pixbuf_new_from_xpm_data((const char**)toolbar_c->pixmap); + pixmap = gtk_image_new_from_pixbuf(pixbuf); + new_widget = + gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu), + GTK_TOOLBAR_CHILD_BUTTON, + NULL, + "", + toolbar_c->tooltip, NULL, + pixmap, NULL, NULL); + gtk_label_set_use_underline( + GTK_LABEL (((GtkToolbarChild*) ( + g_list_last (GTK_TOOLBAR + (tool_menu_title_menu)->children)->data))->label), + TRUE); + gtk_container_set_border_width (GTK_CONTAINER (new_widget), 1); + g_signal_connect ((gpointer) new_widget, + "clicked", + G_CALLBACK (insert_viewer_wrap), + constructor); + gtk_widget_show (new_widget); + + lttv_toolbars_add(instance_toolbar, toolbar_c->con, + toolbar_c->tooltip, + toolbar_c->pixmap, + new_widget); + +} + +void add_menu_constructor(MainWindow *mw, LttvMenuClosure *menu_c) +{ + LttvIAttribute *attributes = mw->attributes; + LttvAttributeValue value; + LttvToolbars * instance_menu; + lttvwindow_viewer_constructor constructor; + GtkWidget * tool_menu_title_menu, *new_widget; + + g_assert(lttv_iattribute_find_by_path(attributes, + "viewers/menu", LTTV_POINTER, &value)); + if(*(value.v_pointer) == NULL) + *(value.v_pointer) = lttv_menus_new(); + instance_menu = (LttvMenus*)*(value.v_pointer); + + + constructor = menu_c->con; + tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu"); + new_widget = + gtk_menu_item_new_with_mnemonic (menu_c->menu_text); + gtk_container_add (GTK_CONTAINER (tool_menu_title_menu), + new_widget); + g_signal_connect ((gpointer) new_widget, "activate", + G_CALLBACK (insert_viewer_wrap), + constructor); + gtk_widget_show (new_widget); + lttv_menus_add(instance_menu, menu_c->con, + menu_c->menu_path, + menu_c->menu_text, + new_widget); +} + +void remove_toolbar_constructor(MainWindow *mw, lttvwindow_viewer_constructor viewer_constructor) +{ + LttvIAttribute *attributes = mw->attributes; + LttvAttributeValue value; + LttvToolbars * instance_toolbar; + lttvwindow_viewer_constructor constructor; + GtkWidget * tool_menu_title_menu, *widget; + + g_assert(lttv_iattribute_find_by_path(attributes, + "viewers/toolbar", LTTV_POINTER, &value)); + if(*(value.v_pointer) == NULL) + *(value.v_pointer) = lttv_toolbars_new(); + instance_toolbar = (LttvToolbars*)*(value.v_pointer); + + tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1"); + widget = lttv_menus_remove(instance_toolbar, viewer_constructor); + gtk_container_remove (GTK_CONTAINER (tool_menu_title_menu), + widget); +} + + +void remove_menu_constructor(MainWindow *mw, lttvwindow_viewer_constructor viewer_constructor) +{ + LttvIAttribute *attributes = mw->attributes; + LttvAttributeValue value; + LttvMenus * instance_menu; + lttvwindow_viewer_constructor constructor; + GtkWidget * tool_menu_title_menu, *widget; + LttvMenuClosure *menu_item_i; + + g_assert(lttv_iattribute_find_by_path(attributes, + "viewers/menu", LTTV_POINTER, &value)); + if(*(value.v_pointer) == NULL) + *(value.v_pointer) = lttv_menus_new(); + instance_menu = (LttvMenus*)*(value.v_pointer); + + widget = lttv_menus_remove(instance_menu, viewer_constructor); + tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu"); + gtk_container_remove (GTK_CONTAINER (tool_menu_title_menu), widget); +} + + +/** + * API parts + */ + + +/** + * Function to register a view constructor so that main window can generate + * a menu item and a toolbar item for the viewer in order to generate a new + * instance easily. A menu entry and toolbar item will be added to each main + * window. + * + * It should be called by init function of the module. + * + * @param menu_path path of the menu item. + * @param menu_text text of the menu item. + * @param pixmap Image shown on the toolbar item. + * @param tooltip tooltip of the toolbar item. + * @param view_constructor constructor of the viewer. + */ + +void lttvwindow_register_constructor + (char * menu_path, + char * menu_text, + char ** pixmap, + char * tooltip, + lttvwindow_viewer_constructor view_constructor) +{ + LttvIAttribute *attributes_global = LTTV_IATTRIBUTE(lttv_global_attributes()); + LttvToolbars * toolbar; + LttvMenus * menu; + LttvToolbarClosure toolbar_c; + LttvMenuClosure menu_c; + LttvAttributeValue value; + + if(pixmap != NULL) { + g_assert(lttv_iattribute_find_by_path(attributes_global, + "viewers/toolbar", LTTV_POINTER, &value)); + toolbar = (LttvToolbars*)*(value.v_pointer); + + if(toolbar == NULL) { + toolbar = lttv_toolbars_new(); + *(value.v_pointer) = toolbar; + } + toolbar_c = lttv_toolbars_add(toolbar, view_constructor, tooltip, pixmap, + NULL); + + g_slist_foreach(g_main_window_list, + (gpointer)add_toolbar_constructor, + &toolbar_c); + } + + if(menu_path != NULL) { + g_assert(lttv_iattribute_find_by_path(attributes_global, + "viewers/menu", LTTV_POINTER, &value)); + menu = (LttvMenus*)*(value.v_pointer); + + if(menu == NULL) { + menu = lttv_menus_new(); + *(value.v_pointer) = menu; + } + menu_c = lttv_menus_add(menu, view_constructor, menu_path, menu_text,NULL); + + g_slist_foreach(g_main_window_list, + (gpointer)add_menu_constructor, + &menu_c); + } +} + + +/** + * Function to unregister the viewer's constructor, release the space + * occupied by menu_path, menu_text, pixmap, tooltip and constructor of the + * viewer. + * + * It will be called when a module is unloaded. + * + * @param view_constructor constructor of the viewer. + */ + + +void lttvwindow_unregister_constructor + (lttvwindow_viewer_constructor view_constructor) +{ + LttvIAttribute *attributes_global = LTTV_IATTRIBUTE(lttv_global_attributes()); + LttvToolbars * toolbar; + LttvMenus * menu; + LttvAttributeValue value; + + g_assert(lttv_iattribute_find_by_path(attributes_global, + "viewers/toolbar", LTTV_POINTER, &value)); + toolbar = (LttvToolbars*)*(value.v_pointer); + + if(toolbar != NULL) { + g_slist_foreach(g_main_window_list, + (gpointer)remove_toolbar_constructor, + view_constructor); + lttv_toolbars_remove(toolbar, view_constructor); + } + + g_assert(lttv_iattribute_find_by_path(attributes_global, + "viewers/menu", LTTV_POINTER, &value)); + menu = (LttvMenus*)*(value.v_pointer); + + if(menu != NULL) { + g_slist_foreach(g_main_window_list, + (gpointer)remove_menu_constructor, + view_constructor); + lttv_menus_remove(menu, view_constructor); + } +} + + +/** + * Function to register a hook function for a viewer to set/update its + * time interval. + * @param tab viewer's tab + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + */ +void lttvwindow_register_time_window_notify(Tab *tab, + LttvHook hook, gpointer hook_data) +{ + LttvAttributeValue value; + LttvHooks * tmp; + g_assert(lttv_iattribute_find_by_path(tab->attributes, + "hooks/updatetimewindow", LTTV_POINTER, &value)); + tmp = (LttvHooks*)*(value.v_pointer); + if(tmp == NULL){ + tmp = lttv_hooks_new(); + *(value.v_pointer) = tmp; + } + lttv_hooks_add(tmp, hook,hook_data, LTTV_PRIO_DEFAULT); +} + + +/** + * Function to unregister a viewer's hook function which is used to + * set/update the time interval of the viewer. + * @param tab viewer's tab + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + */ + +void lttvwindow_unregister_time_window_notify(Tab *tab, + LttvHook hook, gpointer hook_data) +{ + LttvAttributeValue value; + LttvHooks * tmp; + g_assert(lttv_iattribute_find_by_path(tab->attributes, + "hooks/updatetimewindow", LTTV_POINTER, &value)); + tmp = (LttvHooks*)*(value.v_pointer); + if(tmp == NULL) return; + lttv_hooks_remove_data(tmp, hook, hook_data); +} + +/** + * Function to register a hook function for a viewer to set/update its + * traceset. + * @param tab viewer's tab + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + */ + +void lttvwindow_register_traceset_notify(Tab *tab, + LttvHook hook, gpointer hook_data) +{ + LttvAttributeValue value; + LttvHooks * tmp; + g_assert(lttv_iattribute_find_by_path(tab->attributes, + "hooks/updatetraceset", LTTV_POINTER, &value)); + tmp = (LttvHooks*)*(value.v_pointer); + if(tmp == NULL){ + tmp = lttv_hooks_new(); + *(value.v_pointer) = tmp; + } + lttv_hooks_add(tmp, hook, hook_data, LTTV_PRIO_DEFAULT); +} + + +/** + * Function to unregister a viewer's hook function which is used to + * set/update the traceset of the viewer. + * @param tab viewer's tab + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + */ + +void lttvwindow_unregister_traceset_notify(Tab *tab, + LttvHook hook, gpointer hook_data) +{ + LttvAttributeValue value; + LttvHooks * tmp; + g_assert(lttv_iattribute_find_by_path(tab->attributes, + "hooks/updatetraceset", LTTV_POINTER, &value)); + tmp = (LttvHooks*)*(value.v_pointer); + if(tmp == NULL) return; + lttv_hooks_remove_data(tmp, hook, hook_data); +} + +/** + * Function to register a hook function for a viewer to set/update its + * filter. + * @param tab viewer's tab + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + */ + +void lttvwindow_register_filter_notify(Tab *tab, + LttvHook hook, gpointer hook_data) +{ + LttvAttributeValue value; + LttvHooks * tmp; + g_assert(lttv_iattribute_find_by_path(tab->attributes, + "hooks/updatefilter", LTTV_POINTER, &value)); + tmp = (LttvHooks*)*(value.v_pointer); + if(tmp == NULL){ + tmp = lttv_hooks_new(); + *(value.v_pointer) = tmp; + } + lttv_hooks_add(tmp, hook, hook_data, LTTV_PRIO_DEFAULT); +} + + +/** + * Function to unregister a viewer's hook function which is used to + * set/update the filter of the viewer. + * @param tab viewer's tab + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + */ + +void lttvwindow_unregister_filter_notify(Tab *tab, + LttvHook hook, + gpointer hook_data) +{ + LttvAttributeValue value; + LttvHooks * tmp; + g_assert(lttv_iattribute_find_by_path(tab->attributes, + "hooks/updatefilter", LTTV_POINTER, &value)); + tmp = (LttvHooks*)*(value.v_pointer); + if(tmp == NULL) return; + lttv_hooks_remove_data(tmp, hook, hook_data); +} + +/** + * Function to register a hook function for a viewer to set/update its + * current time. + * @param tab viewer's tab + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + */ + +void lttvwindow_register_current_time_notify(Tab *tab, + LttvHook hook, gpointer hook_data) +{ + LttvAttributeValue value; + LttvHooks * tmp; + g_assert(lttv_iattribute_find_by_path(tab->attributes, + "hooks/updatecurrenttime", LTTV_POINTER, &value)); + tmp = (LttvHooks*)*(value.v_pointer); + if(tmp == NULL){ + tmp = lttv_hooks_new(); + *(value.v_pointer) = tmp; + } + lttv_hooks_add(tmp, hook, hook_data, LTTV_PRIO_DEFAULT); +} + + +/** + * Function to unregister a viewer's hook function which is used to + * set/update the current time of the viewer. + * @param tab viewer's tab + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + */ + +void lttvwindow_unregister_current_time_notify(Tab *tab, + LttvHook hook, gpointer hook_data) +{ + LttvAttributeValue value; + LttvHooks * tmp; + g_assert(lttv_iattribute_find_by_path(tab->attributes, + "hooks/updatecurrenttime", LTTV_POINTER, &value)); + tmp = (LttvHooks*)*(value.v_pointer); + if(tmp == NULL) return; + lttv_hooks_remove_data(tmp, hook, hook_data); +} + + +/** + * Function to register a hook function for a viewer to show + * the content of the viewer. + * @param tab viewer's tab + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + */ + +void lttvwindow_register_show_notify(Tab *tab, + LttvHook hook, gpointer hook_data) +{ + LttvAttributeValue value; + LttvHooks * tmp; + g_assert(lttv_iattribute_find_by_path(tab->attributes, + "hooks/showviewer", LTTV_POINTER, &value)); + tmp = (LttvHooks*)*(value.v_pointer); + if(tmp == NULL){ + tmp = lttv_hooks_new(); + *(value.v_pointer) = tmp; + } + lttv_hooks_add(tmp, hook, hook_data, LTTV_PRIO_DEFAULT); +} + + +/** + * Function to unregister a viewer's hook function which is used to + * show the content of the viewer.. + * @param tab viewer's tab + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + */ + +void lttvwindow_unregister_show_notify(Tab *tab, + LttvHook hook, gpointer hook_data) +{ + LttvAttributeValue value; + LttvHooks * tmp; + g_assert(lttv_iattribute_find_by_path(tab->attributes, + "hooks/showviewer", LTTV_POINTER, &value)); + tmp = (LttvHooks*)*(value.v_pointer); + if(tmp == NULL) return; + lttv_hooks_remove_data(tmp, hook, hook_data); +} + +/** + * Function to register a hook function for a viewer to set/update the + * dividor of the hpane. + * @param tab viewer's tab + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + */ + +void lttvwindow_register_dividor(Tab *tab, + LttvHook hook, gpointer hook_data) +{ + LttvAttributeValue value; + LttvHooks * tmp; + g_assert(lttv_iattribute_find_by_path(tab->attributes, + "hooks/hpanedividor", LTTV_POINTER, &value)); + tmp = (LttvHooks*)*(value.v_pointer); + if(tmp == NULL){ + tmp = lttv_hooks_new(); + *(value.v_pointer) = tmp; + } + lttv_hooks_add(tmp, hook, hook_data, LTTV_PRIO_DEFAULT); +} + + +/** + * Function to unregister a viewer's hook function which is used to + * set/update hpane's dividor of the viewer. + * It will be called by the destructor of the viewer. + * @param tab viewer's tab + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + */ + +void lttvwindow_unregister_dividor(Tab *tab, + LttvHook hook, gpointer hook_data) +{ + LttvAttributeValue value; + LttvHooks * tmp; + g_assert(lttv_iattribute_find_by_path(tab->attributes, + "hooks/hpanedividor", LTTV_POINTER, &value)); + tmp = (LttvHooks*)*(value.v_pointer); + if(tmp == NULL) return; + lttv_hooks_remove_data(tmp, hook, hook_data); +} + + +/** + * Update the status bar whenever something changed in the viewer. + * @param tab viewer's tab + * @param info the message which will be shown in the status bar. + */ + +void lttvwindow_report_status(Tab *tab, const char *info) +{ + //FIXME + g_warning("update_status not implemented in viewer.c"); + // Use tab->mw for status +} + +/** + * Function to set the time interval of the current tab. + * It will be called by a viewer's signal handle associated with + * the move_slider signal + * @param tab viewer's tab + * @param time_interval a pointer where time interval is stored. + */ + +void lttvwindow_report_time_window(Tab *tab, + const TimeWindow *time_window) +{ + set_time_window(tab, time_window); + set_time_window_adjustment(tab, time_window); +} + + +/** + * Function to set the current time/event of the current tab. + * It will be called by a viewer's signal handle associated with + * the button-release-event signal + * @param tab viewer's tab + * @param time a pointer where time is stored. + */ + +void lttvwindow_report_current_time(Tab *tab, + const LttTime *time) +{ + LttvAttributeValue value; + LttvHooks * tmp; + tab->current_time = *time; + g_assert(lttv_iattribute_find_by_path(tab->attributes, + "hooks/updatecurrenttime", LTTV_POINTER, &value)); + tmp = (LttvHooks*)*(value.v_pointer); + + if(tmp == NULL)return; + lttv_hooks_call(tmp, &tab->current_time); +} + +/** + * Function to set the position of the hpane's dividor (viewer). + * It will be called by a viewer's signal handle associated with + * the motion_notify_event event/signal + * @param tab viewer's tab + * @param position position of the hpane's dividor. + */ + +void lttvwindow_report_dividor(Tab *tab, gint position) +{ + LttvAttributeValue value; + LttvHooks * tmp; + g_assert(lttv_iattribute_find_by_path(tab->attributes, + "hooks/hpanedividor", LTTV_POINTER, &value)); + tmp = (LttvHooks*)*(value.v_pointer); + if(tmp == NULL) return; + lttv_hooks_call(tmp, &position); +} + +/** + * Function to set the focused pane (viewer). + * It will be called by a viewer's signal handle associated with + * the grab_focus signal + * @param tab viewer's tab + * @param top_widget the top widget containing all the other widgets of the + * viewer. + */ + +void lttvwindow_report_focus(Tab *tab, GtkWidget *top_widget) +{ + gtk_multi_vpaned_set_focus((GtkWidget*)tab->multi_vpaned, + GTK_PANED(gtk_widget_get_parent(top_widget))); +} + + +/** + * Function to request data in a specific time interval to the main window. The + * event request servicing is differed until the glib idle functions are + * called. + * + * The viewer has to provide hooks that should be associated with the event + * request. + * + * Either start time or start position must be defined in a EventRequest + * structure for it to be valid. + * + * end_time, end_position and num_events can all be defined. The first one + * to occur will be used as end criterion. + * + * @param tab viewer's tab + * @param events_requested the structure of request from. + */ + +void lttvwindow_events_request(Tab *tab, + const EventsRequest *events_request) +{ + EventsRequest *alloc = g_new(sizeof(EventsRequest,1)); + *alloc = *events_request; + + tab->events_requests = g_slist_append(tab->events_requests, alloc); + + if(!tab->events_request_pending) + { + /* Redraw has +20 priority. We want a prio higher than that, so +19 */ + g_idle_add_full((G_PRIORITY_HIGH_IDLE + 19), + (GSourceFunc)execute_events_requests, + tab, + NULL); + tab->events_request_pending = TRUE; + } +} + + +/** + * Function to remove data requests related to a viewer. + * + * The existing requests's viewer gpointer is compared to the pointer + * given in argument to establish which data request should be removed. + * + * @param tab the tab the viewer belongs to. + * @param viewer a pointer to the viewer data structure + */ + +gint find_viewer (const EventsRequest *a, gconstpointer b) +{ + return (a->viewer != b); +} + + +void lttvwindow_events_request_remove_all(Tab *tab, + gconstpointer viewer) +{ + GSList *element; + + while((element = + g_slist_find_custom(tab->events_requests, viewer, + (GCompareFunc)find_viewer)) + != NULL) { + EventRequest *events_request = (EventsRequest *)element->data; + if(events_request->servicing == TRUE) { + lttv_hooks_call(events_request->after_request, NULL); + } + g_free(events_request); + tab->events_requests = g_slist_remove_link(tab->events_requests, element); + + } +} + + + +/** + * Function to get the current time interval shown on the current tab. + * It will be called by a viewer's hook function to update the + * shown time interval of the viewer and also be called by the constructor + * of the viewer. + * @param tab viewer's tab + * @param time_interval a pointer where time interval will be stored. + */ + +const TimeWindow *lttvwindow_get_time_window(Tab *tab) +{ + return &(tab->time_window); + +} + + +/** + * Function to get the current time/event of the current tab. + * It will be called by a viewer's hook function to update the + * current time/event of the viewer. + * @param tab viewer's tab + * @param time a pointer where time will be stored. + */ + +const LttTime *lttvwindow_get_current_time(Tab *tab) +{ + return &(tab->current_time); +} + + +/** + * Function to get the filter of the current tab. + * It will be called by the constructor of the viewer and also be + * called by a hook funtion of the viewer to update its filter. + * @param tab viewer's tab + * @param filter, a pointer to a filter. + */ +const lttv_filter *lttvwindow_get_filter(Tab *tab) +{ + //FIXME + g_warning("lttvwindow_get_filter not implemented in viewer.c"); +} + + +/** + * Function to get the stats of the traceset + * @param tab viewer's tab + */ + +LttvTracesetStats* lttvwindow_get_traceset_stats(Tab *tab) +{ + return tab->traceset_info->traceset_context; +} + + +LttvTracesetContext* lttvwindow_get_traceset_context(Tab *tab) +{ + return (LttvTracesetContext*)tab->traceset_info->traceset_context; +} diff --git a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h new file mode 100644 index 00000000..1bf2d560 --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h @@ -0,0 +1,718 @@ +/* This file is part of the Linux Trace Toolkit Graphic User Interface + * Copyright (C) 2003-2004 Xiangxiu Yang, Mathieu Desnoyers + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +/* +This file is what every viewer plugin writer should refer to. + + +Module Related API + +A viewer plugin is, before anything, a plugin. As a dynamically loadable +module, it thus has an init and a destroy function called whenever it is +loaded/initialized and unloaded/destroyed. A graphical module depends on +lttvwindow for construction of its viewer instances. In order to achieve this, +it must register its constructor function to the main window along with +button description or text menu entry description. A module keeps a list of +every viewer that currently sits in memory so it can destroy them before the +module gets unloaded/destroyed. + +The contructor registration to the main windows adds button and menu entry +to each main window, thus allowing instanciation of viewers. + + +Main Window + +The main window is a container that offers menus, buttons and a notebook. Some +of those menus and buttons are part of the core of the main window, others +are dynamically added and removed when modules are loaded/unloaded. + +The notebook contains as much tabs as wanted. Each tab is linked with a +set of traces (traceset). Each trace contains many tracefiles (one per cpu). +A trace corresponds to a kernel being traced. A traceset corresponds to +many traces read together. The time span of a traceset goes from the +earliest start of all the traces to the latest end of all the traces. + +Inside each tab are added the viewers. When they interact with the main +window through the lttvwindow API, they affect the other viewers located +in the same tab as they are. + +The insertion of many viewers in a tab permits a quick look at all the +information wanted in a glance. The main window does merge the read requests +from all the viewers in the same tab in a way that every viewer will get exactly +the events it asked for, while the event reading loop and state update are +shared. It improves performance of events delivery to the viewers. + + + +Viewer Instance Related API + +The lifetime of a viewer is as follows. The viewer constructor function is +called each time an instance view is created (one subwindow of this viewer +type is created by the user either by clicking on the menu item or the button +corresponding to the viewer). Thereafter, the viewer gets hooks called for +different purposes by the window containing it. These hooks are detailed +below. It also has to deal with GTK Events. Finally, it can be destructed by +having its top level widget unreferenced by the main window or by any +GTK Event causing a "destroy-event" signal on the its top widget. Another +possible way for it do be destroyed is if the module gets unloaded. The module +unload function will have to emit a "destroy" signal on each top level widget +of all instances of its viewers. + + +Notices from Main Window + +time_window : This is the time interval visible on the viewer's tab. Every + viewer that cares about being synchronised by respect to the + time with other viewers should register to this notification. + They should redraw all or part of their display when this occurs. + +traceset : This notification is called whenever a trace is added/removed + from the traceset. As it affects all the data displayed by the + viewer, it sould redraw itself totally. + +filter : FIXME : describe.. + +current_time: Being able to zoom nearer a specific time or highlight a specific + time on every viewer in synchronicity implies that the viewer + has to shown a visual sign over the drawing or select an event + when it receives this notice. It should also inform the main + window with the appropriate report API function when a user + selects a specific time as being the current time. + +dividor : This notice links the positions of the horizontal dividors + between the graphic display zone of every viewer and their Y axis, + typically showing processes, cpus, ... + + +FIXME : Add background computation explanation here +background_init: prepare for background computation (comes after show_end). +process_trace for background: done in small chunks in gtk_idle, hooks called. +background_end: remove the hooks and perhaps update the window. + + +Reporting Changes to the Main Window + +In most cases, the enclosing window knows about updates such as described in the +Notification section higher. There are a few cases, however, where updates are +caused by actions known by a view instance. For example, clicking in a view may +update the current time; all viewers within the same window must be told about +the new current time to change the currently highlighted time point. A viewer +reports such events by calling lttvwindow_report_current_time on its lttvwindow. +The lttvwindow will consequently call current_time_notify for each of its +contained viewers. + + +Available report methods are : + +lttvwindow_report_status : reports the text of the status bar. +lttvwindow_report_time_window : reports the new time window. +lttvwindow_report_current_time : reports the new current time. +lttvwindow_report_dividor : reports the new horizontal dividor's position. +lttvwindow_report_focus : One on the widgets in the viewer has the keyboard's + focus from GTK. + + + +Requesting Events to Main Window + +Events can be requested by passing a EventsRequest structure to the main window. +They will be delivered later when the next g_idle functions will be called. +Event delivery is done by calling the event hook for this event ID, or the +main event hooks. A pointer to the EventsRequest structure is passed as +hook_data to the event hooks of the viewers. + +EventsRequest consists in +- a pointer to the viewer specific data structure +- a start timestamp or position +- a stop_flag, ending the read process when set to TRUE +- a end timestamp and/or position and/or number of events to read +- hook lists to call for traceset/trace/tracefile begin and end, and for each + event (event hooks and event_by_id hooks). + +The main window will deliver events for every EventRequests it has pending +through an algorithm that guarantee that all events requested, and only them, +will be delivered to the viewer between the call of the tracefile_begin hooks +and the call of the tracefile_end hooks. + +If a viewer wants to stop the event request at a certain point inside the event +hooks, it has to set the stop_flag to TRUE and return TRUE from the hook +function. Then return value will stop the process traceset. Then, the main +window will look for the stop_flag and remove the EventRequests from its lists, +calling the process_traceset_end for this request (it removes hooks from the +context and calls the after hooks). + +It no stop_flag is rose, the end timestamp, end position or number of events to +read has to be reached to determine the end of the request. Otherwise, +the end of traceset does determine it. + + +GTK Events + +Events and Signals + +GTK is quite different from the other graphical toolkits around there. The main +difference resides in that there are many X Windows inside one GtkWindow, +instead of just one. That means that X events are delivered by the glib main +loop directly to the widget corresponding to the GdkWindow affected by the X +event. + +Event delivery to a widget emits a signal on that widget. Then, if a handler +is connected to this widget's signal, it will be executed. There are default +handlers for signals, connected at class instantiation time. There is also +the possibility to connect other handlers to these signals, which is what +should be done in most cases when a viewer needs to interact with X in any +way. + + + +Signal emission and propagation is described there : + +http://www.gtk.org/tutorial/sec-signalemissionandpropagation.html + +For further information on the GTK main loop (now a wrapper over glib main loop) +see : + +http://developer.gnome.org/doc/API/2.0/gtk/gtk-General.html +http://developer.gnome.org/doc/API/2.0/glib/glib-The-Main-Event-Loop.html + + +For documentation on event handling in GTK/GDK, see : + +http://developer.gnome.org/doc/API/2.0/gdk/gdk-Events.html +http://developer.gnome.org/doc/API/2.0/gdk/gdk-Event-Structures.html + + +Signals can be connected to handlers, emitted, propagated, blocked, +stopped. See : + +http://developer.gnome.org/doc/API/2.0/gobject/gobject-Signals.html + + + + +The "expose_event" + +Provides the exposed region in the GdkEventExpose structure. + +There are two ways of dealing with exposures. The first one is to directly draw +on the screen and the second one is to draw in a pixmap buffer, and then to +update the screen when necessary. + +In the first case, the expose event will be responsible for registering hooks to +process_traceset and require time intervals to the main window. So, in this +scenario, if a part of the screen is damaged, the trace has to be read to +redraw the screen. + +In the second case, with a pixmap buffer, the expose handler is only responsible +of showing the pixmap buffer on the screen. If the pixmap buffer has never +been filled with a drawing, the expose handler may ask for it to be filled. + +The interest of using events request to the main window instead of reading the +events directly from the trace comes from the fact that the main window +does merge requests from the different viewers in the same tab so that the +read loop and the state update is shared. As viewers will, in the common +scenario, request the same events, only one pass through the trace that will +call the right hooks for the right intervals will be done. + +When the traceset read is over for a events request, the traceset_end hook is +called. It has the responsibility of finishing the drawing if some parts +still need to be drawn and to show it on the screen (if the viewer uses a pixmap +buffer). + +It can add dotted lines and such visual effects to enhance the user's +experience. + + +FIXME : explain other important events + +*/ + + +#ifndef VIEWER_H +#define VIEWER_H + +/*! \file lttvwindow.h + * \brief API used by the graphical viewers to interact with their top window. + * + * Main window (lttvwindow module) is the place to contain and display viewers. + * Viewers (lttv plugins) interact with main window through this API. + * This header file should be included in each graphic module. + * + */ + +#include +#include +#include +#include +#include +#include +#include +//FIXME (not ready yet) #include + + +/* Module Related API */ + + +/* constructor a the viewer */ +//FIXME explain LttvTracesetSelector and key +typedef GtkWidget * (*lttvwindow_viewer_constructor) + (Tab *tab, LttvTracesetSelector * s, char *key); + + +/** + * Function to register a view constructor so that main window can generate + * a menu item and a toolbar item for the viewer in order to generate a new + * instance easily. A menu entry and toolbar item will be added to each main + * window. + * + * It should be called by init function of the module. + * + * @param menu_path path of the menu item. NULL : no menu entry. + * @param menu_text text of the menu item. + * @param pixmap Image shown on the toolbar item. NULL : no button. + * @param tooltip tooltip of the toolbar item. + * @param view_constructor constructor of the viewer. + */ + +void lttvwindow_register_constructor + (char * menu_path, + char * menu_text, + char ** pixmap, + char * tooltip, + lttvwindow_viewer_constructor view_constructor); + + +/** + * Function to unregister the viewer's constructor, release the space + * occupied by menu_path, menu_text, pixmap, tooltip and constructor of the + * viewer. + * + * It will be called when a module is unloaded. + * + * @param view_constructor constructor of the viewer. + */ + +void lttvwindow_unregister_constructor + (lttvwindow_viewer_constructor view_constructor); + + + + +/* Viewer Instance Related API */ + +/** + * Structure used as hook_data for the time_window_notify hook. + */ +typedef struct _TimeWindowNotifyData { + TimeWindow *new_time_window; + TimeWindow *old_time_window; +} TimeWindowNotifyData; + + +/** + * Function to register a hook function that will be called by the main window + * when the time interval needs to be updated. + * + * This register function is typically called by the constructor of the viewer. + * + * @param tab the tab the viewer belongs to. + * @param hook hook that sould be called by the main window when the time + * interval changes. This hook function takes a + * TimeWindowNotifyData* as call_data. + * @param hook_data hook data associated with the hook function. It will + * be typically a pointer to the viewer's data structure. + */ + +void lttvwindow_register_time_window_notify(Tab *tab, + LttvHook hook, + gpointer hook_data); + + +/** + * Function to unregister the time_window notification hook. + * + * This unregister function is typically called by the destructor of the viewer. + * + * @param tab the tab the viewer belongs to. + * @param hook hook that sould be called by the main window when the time + * interval changes. This hook function takes a + * TimeWindowNotifyData* as call_data. + * @param hook_data hook data associated with the hook function. It will + * be typically a pointer to the viewer's data structure. + */ + +void lttvwindow_unregister_time_window_notify(Tab *tab, + LttvHook hook, + gpointer hook_data); + + +/** + * Function to register a hook function that will be called by the main window + * when the traceset is changed. That means that the viewer must redraw + * itself completely or check if it's affected by the particular change to the + * traceset. + * + * This register function is typically called by the constructor of the viewer. + * + * @param tab the tab the viewer belongs to. + * @param hook hook that should be called whenever a change to the traceset + * occurs. The call_data of this hook is a NULL pointer. + * @param hook_data hook data associated with the hook function. It will + * be typically a pointer to the viewer's data structure. + */ + +void lttvwindow_register_traceset_notify(Tab *tab, + LttvHook hook, + gpointer hook_data); + + +/** + * Function to unregister the traceset_notify hook. + * + * @param tab the tab the viewer belongs to. + * @param hook hook that should be called whenever a change to the traceset + * occurs. The call_data of this hook is a NULL pointer. + * @param hook_data hook data associated with the hook function. It will + * be typically a pointer to the viewer's data structure. + */ + +void lttvwindow_unregister_traceset_notify(Tab *tab, + LttvHook hook, + gpointer hook_data); + + +/** + * Function to register a hook function for a viewer to set/update its + * filter. + * + * FIXME : Add information about what a filter is as seen from a viewer and how + * to use it. + * + * This register function is typically called by the constructor of the viewer. + * + * @param tab the tab the viewer belongs to. + * @param hook hook function called by the main window when a filter change + * occurs. + * @param hook_data hook data associated with the hook function. It will + * be typically a pointer to the viewer's data structure. + */ + +void lttvwindow_register_filter_notify(Tab *tab, + LttvHook hook, + gpointer hook_data); + + +/** + * Function to unregister a viewer's hook function which is used to + * set/update the filter of the viewer. + * + * This unregistration is called by the destructor of the viewer. + * + * @param tab the tab the viewer belongs to. + * @param hook hook function called by the main window when a filter change + * occurs. + * @param hook_data hook data associated with the hook function. It will + * be typically a pointer to the viewer's data structure. + */ + +void lttvwindow_unregister_filter_notify(Tab *tab, + LttvHook hook, + gpointer hook_data); + + +/** + * Function to register a hook function for a viewer to set/update its + * current time. + * + * @param tab the tab the viewer belongs to. + * @param hook hook function of the viewer that updates the current time. The + * call_data is a LttTime* representing the new current time. + * @param hook_data hook data associated with the hook function. It will + * be typically a pointer to the viewer's data structure. + */ + +void lttvwindow_register_current_time_notify(Tab *tab, + LttvHook hook, + gpointer hook_data); + + +/** + * Function to unregister a viewer's hook function which is used to + * set/update the current time of the viewer. + * @param tab the tab the viewer belongs to. + * @param hook hook function of the viewer that updates the current time. The + * call_data is a LttTime* representing the new current time. + * @param hook_data hook data associated with the hook function. It will + * be typically a pointer to the viewer's data structure. + */ + +void lttvwindow_unregister_current_time_notify(Tab *tab, + LttvHook hook, + gpointer hook_data); + + +/** + * Function to register a hook function for a viewer to set/update the + * dividor of the hpane. It provides a way to make the horizontal + * dividors of all the viewers linked together. + * + * @param tab the tab the viewer belongs to. + * @param hook hook function of the viewer that will be called whenever a + * dividor changes in another viewer. The call_data of this hook + * is a gint*. The value of the integer is the new position of the + * hpane dividor. + * @param hook_data hook data associated with the hook function. It will + * be typically a pointer to the viewer's data structure. + */ + +void lttvwindow_register_dividor(Tab *tab, + LttvHook hook, + gpointer hook_data); + + +/** + * Function to unregister a viewer's hook function which is used to + * set/update hpane's dividor of the viewer. + * + * @param tab the tab the viewer belongs to. + * @param hook hook function of the viewer that will be called whenever a + * dividor changes in another viewer. The call_data of this hook + * is a gint*. The value of the integer is the new position of the + * hpane dividor. + * @param hook_data hook data associated with the hook function. It will + * be typically a pointer to the viewer's data structure. + */ + +void lttvwindow_unregister_dividor(Tab *tab, + LttvHook hook, + gpointer hook_data); + + + +/** + * This method reports the information to show on the status bar in the + * main window. + * + * @param tab the tab the viewer belongs to. + * @param info the message which will be shown in the status bar. + */ + +void lttvwindow_report_status(Tab *tab, const char *info); + + +/** + * Function to set the time interval of the current tab.a + * + * @param tab the tab the viewer belongs to. + * @param time_interval pointer to the time interval value. + */ + +void lttvwindow_report_time_window(Tab *tab, + const TimeWindow *time_window); + +/** + * Function to set the current time/event of the current tab. + * It will be called by a viewer's signal handle associated with + * the button-release-event signal + * @param tab the tab the viewer belongs to. + * @param time a pointer where time is stored. + */ + +void lttvwindow_report_current_time(Tab *tab, + const LttTime *time); + + +/** + * Function to set the position of the hpane's dividor (viewer). + * It will typically be called by a viewer's signal handle associated + * with the motion_notify_event event/signal. + * + * @param tab the tab the viewer belongs to. + * @param position position of the hpane's dividor. + */ + +void lttvwindow_report_dividor(Tab *tab, gint position); + +/** + * Function to set the focused viewer of the tab. + * It will be called by a viewer's signal handle associated with + * the grab_focus signal of all widgets in the viewer. + * + * @param tab the tab the viewer belongs to. + * @param top_widget the top widget containing all the other widgets of the + * viewer. + */ +void lttvwindow_report_focus(Tab *tab, + GtkWidget *top_widget); + + +/* Structure sent to the events request hook */ + /* Value considered as empty */ +typedef struct _EventsRequest { + gpointer viewer_data; /* Unset : NULL */ + gboolean servicing; /* service in progress: TRUE */ + LttTime start_time;/* Unset : { G_MAXUINT, G_MAXUINT }*/ + LttvTracesetContextPosition *start_position; /* Unset : NULL */ + gboolean stop_flag; /* Continue:TRUE Stop:FALSE */ + LttTime end_time;/* Unset : { G_MAXUINT, G_MAXUINT } */ + guint num_events; /* Unset : G_MAXUINT */ + LttvTracesetContextPosition *end_position; /* Unset : NULL */ + LttvHooks *before_chunk_traceset; /* Unset : NULL */ + LttvHooks *before_chunk_trace; /* Unset : NULL */ + LttvHooks *before_chunk_tracefile;/* Unset : NULL */ + LttvHooks *event; /* Unset : NULL */ + LttvHooksById *event_by_id; /* Unset : NULL */ + LttvHooks *after_chunk_tracefile; /* Unset : NULL */ + LttvHooks *after_chunk_trace; /* Unset : NULL */ + LttvHooks *after_chunk_traceset; /* Unset : NULL */ + LttvHooks *before_request; /* Unset : NULL */ + LttvHooks *after_request /* Unset : NULL */ +} EventsRequest; + + +/** + * Function to request data in a specific time interval to the main window. The + * event request servicing is differed until the glib idle functions are + * called. + * + * The viewer has to provide hooks that should be associated with the event + * request. + * + * Either start time or start position must be defined in a EventRequest + * structure for it to be valid. + * + * end_time, end_position and num_events can all be defined. The first one + * to occur will be used as end criterion. + * + * @param tab the tab the viewer belongs to. + * @param events_requested Details about the event request. + */ + +void lttvwindow_events_request(Tab *tab, + const EventsRequest *events_request); + +/** + * Function to remove data requests related to a viewer. + * + * The existing requests's viewer gpointer is compared to the pointer + * given in argument to establish which data request should be removed. + * + * @param tab the tab the viewer belongs to. + * @param viewer a pointer to the viewer data structure + */ + +void lttvwindow_events_request_remove_all(Tab *tab, + gconstpointer viewer); + + +typedef struct _BackgroundRequest { + gchar *hook_path; /* Hook path in global attributes, where all standard hooks + are : i.e. /TraceState/Statistics/ModuleName */ + gchar *trace_path; /* path_to_trace */ +} BackgroundRequest; + +typedef struct _BackgroundNotify { + gchar *trace_path; /* path_to_trace */ + LttTime notify_time; + LttvTracesetContextPosition *notify_position; + LttvHooks *notify; /* Hook to call when the notify is + passed, or at the end of trace */ +} BackgroundNotify; + +/** + * Function to request data from a specific trace + * + * @param bg_request Request specification + */ + +void lttvwindow_background_request_queue(const BackgroundRequest *bg_request); + +/** + * Register a callback to be called when requested data is passed in the next + * queued background processing. + * + * @param bg_request Request specification + */ + +void lttvwindow_background_notify_queue(const BackgroundNotify *bg_notify); + + +/** + * Register a callback to be called when requested data is passed in the current + * background processing. + * + * @param bg_request Request specification + */ + +void lttvwindow_background_notify_current(const BackgroundNotify *bg_notify); + + +/** + * Function to get the current time window of the current tab. + * + * @param tab the tab the viewer belongs to. + * @return a pointer to the current tab's time interval. + */ + +const TimeWindow *lttvwindow_get_time_window(Tab *tab); + + +/** + * Function to get the current time of the current tab. + * + * @param tab the tab the viewer belongs to. + * @return a pointer to the current tab's current time. + */ + +const LttTime *lttvwindow_get_current_time(Tab *tab); + + +/** + * Function to get the filter of the current tab. + * @param main_win, the main window the viewer belongs to. + * @param filter, a pointer to a filter. + */ + +//FIXME +typedef void lttv_filter; +//FIXME +const lttv_filter *lttvwindow_get_filter(Tab *tab); + + +/** + * Function to get the stats of the traceset + * It must be non const so the viewer can modify it. + * FIXME : a set/get pair of functions would be more appropriate here. + * @param tab the tab the viewer belongs to. + * @return A pointer to Traceset statistics. + */ + +LttvTracesetStats* lttvwindow_get_traceset_stats(Tab *tab); + +/** + * Function to get the context of the traceset + * It must be non const so the viewer can add and remove hooks from it. + * @param tab the tab the viewer belongs to. + * @return Context of the current tab. + */ + + +LttvTracesetContext* lttvwindow_get_traceset_context(Tab *tab); + + +#endif //VIEWER_H diff --git a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/menu.h b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/menu.h index a2f10ffa..785aa746 100644 --- a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/menu.h +++ b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/menu.h @@ -21,15 +21,15 @@ #include #include -#include +#include typedef GArray LttvMenus; typedef struct _LttvMenuClosure { lttvwindow_viewer_constructor con; - char * menuPath; - char * menuText; + char * menu_path; + char * menu_text; GtkWidget *widget; } LttvMenuClosure; diff --git a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/toolbar.h b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/toolbar.h index a7eaf817..e80d9ed6 100644 --- a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/toolbar.h +++ b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/toolbar.h @@ -20,7 +20,7 @@ #define TOOLBAR_H #include -#include +#include #include typedef GArray LttvToolbars; -- 2.34.1