#include <glib.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
#include <string.h>
#include <ltt/ltt.h>
#include <lttv/print.h>
#include <lttvwindow/lttvwindow.h>
#include <lttvwindow/lttvwindowtraces.h>
+#include <lttvwindow/lttv_plugin_tab.h>
#include "hGuiEventsInsert.xpm"
#define abs(a) (((a)<0)?(-a):(a))
#define max(a,b) ((a)>(b)?(a):(b))
+#define min(a,b) ((a)<(b)?(a):(b))
/** Array containing instanced objects. Used when module is unloaded */
static GSList *g_event_viewer_data_list = NULL ;
typedef struct _EventViewerData {
Tab * tab;
+ LttvPluginTab *ptab;
LttvHooks * event_hooks;
/* previous value is used to determine if it is a page up/down or
guint32 last_tree_update_time; /* To filter out repeat keys */
+ guint num_events; /* Number of events processed */
+
} EventViewerData ;
/** hook functions for update time interval, current time ... */
static void request_background_data(EventViewerData *event_viewer_data);
//! Event Viewer's constructor hook
-GtkWidget *h_gui_events(Tab *tab);
+GtkWidget *h_gui_events(LttvPlugin *plugin);
//! Event Viewer's constructor
-EventViewerData *gui_events(Tab *tab);
+EventViewerData *gui_events(LttvPluginTab *ptab);
//! Event Viewer's destructor
void gui_events_destructor(EventViewerData *event_viewer_data);
void gui_events_free(EventViewerData *event_viewer_data);
* @return The widget created.
*/
GtkWidget *
-h_gui_events(Tab * tab)
+h_gui_events(LttvPlugin *plugin)
{
- EventViewerData* event_viewer_data = gui_events(tab) ;
+ LttvPluginTab *ptab = LTTV_PLUGIN_TAB(plugin);
+ EventViewerData* event_viewer_data = gui_events(ptab) ;
if(event_viewer_data)
return event_viewer_data->top_widget;
else return NULL;
* @return The Event viewer data created.
*/
EventViewerData *
-gui_events(Tab *tab)
+gui_events(LttvPluginTab *ptab)
{
LttTime end;
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
EventViewerData* event_viewer_data = g_new(EventViewerData,1) ;
-
+ Tab *tab = ptab->tab;
event_viewer_data->tab = tab;
+ event_viewer_data->ptab = ptab;
LttvTracesetContext * tsc =
lttvwindow_get_traceset_context(event_viewer_data->tab);
gint num_traces = lttv_traceset_number(tsc->ts);
gint i;
LttvTrace *trace;
+ LttvTraceState *tstate;
LttvHooks *background_ready_hook =
lttv_hooks_new();
for(i=0;i<num_traces;i++) {
trace = lttv_traceset_get(tsc->ts, i);
+ tstate = LTTV_TRACE_STATE(tsc->traces[i]);
- if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace)==FALSE) {
+ if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace)==FALSE
+ && !tstate->has_precomputed_states) {
if(lttvwindowtraces_get_in_progress(g_quark_from_string("state"),
trace) == FALSE) {
event_viewer_data->background_info_waiting++;
}
} else {
- /* Data ready. Be its nature, this viewer doesn't need to have
+ /* Data ready. By its nature, this viewer doesn't need to have
* its data ready hook called htere, because a background
* request is always linked with a redraw.
*/
gtk_adjustment_set_value(event_viewer_data->vadjust_c,
gtk_adjustment_get_value(event_viewer_data->vadjust_c) + 1);
break;
+ default:
+ g_error("Only scroll up and down expected");
}
return TRUE;
}
gtk_tree_view_column_cell_get_size(column, NULL, NULL, NULL, NULL, &height);
-#if GTK_CHECK_VERSION(2.4.15)
gint vertical_separator;
gtk_widget_style_get (GTK_WIDGET (TreeView),
"vertical-separator", &vertical_separator,
NULL);
height += vertical_separator;
-#endif
+
return height;
}
}
#endif //0
-
-
-
-
-
+static gboolean events_check_handler(guint count, gboolean *stop_flag)
+{
+ if(count % CHECK_GDK_INTERVAL == 0) {
+ gtk_main_iteration_do(FALSE);
+ if(*stop_flag)
+ return TRUE;
+ else
+ return FALSE;
+ } else return FALSE;
+}
static void get_events(double new_value, EventViewerData *event_viewer_data)
{
guint i;
gboolean seek_by_time;
+ if(lttvwindow_preempt_count > 0) return;
+
double value = new_value - event_viewer_data->previous_value;
+ /* Set stop button status for foreground processing */
+ event_viewer_data->tab->stop_foreground = FALSE;
+ lttvwindow_events_request_disable();
+
/* See where we have to scroll... */
ScrollDirection direction;
gint relative_position;
*/
if(relative_position > 0) {
guint count;
- count = lttv_process_traceset_seek_n_forward(tsc, relative_position,
- event_viewer_data->main_win_filter);
+ count += lttv_process_traceset_seek_n_forward(tsc, relative_position,
+ event_viewer_data->main_win_filter, events_check_handler,
+ &event_viewer_data->tab->stop_foreground);
} else if(relative_position < 0) {
guint count;
LttTime time_diff = ltt_time_sub(last_event_time, first_event_time);
if(ltt_time_compare(time_diff, ltt_time_zero) == 0)
time_diff = seek_back_default_offset;
- count = lttv_process_traceset_seek_n_backward(tsc, abs(relative_position),
+
+ count = lttv_process_traceset_seek_n_backward(tsc,
+ abs(relative_position),
time_diff,
(seek_time_fct)lttv_state_traceset_seek_time_closest,
- event_viewer_data->main_win_filter);
+ event_viewer_data->main_win_filter,
+ events_check_handler,
+ &event_viewer_data->tab->stop_foreground);
} /* else 0 : do nothing : we are already at the beginning position */
lttv_traceset_context_position_destroy(pos);
/* Mathieu :
* I make the choice not to use the mainwindow lttvwindow API here : the idle
* loop might have a too low priority, and we want good update while
- * scrolling.
+ * scrolling. However, we call the gdk loop to get events periodically so the
+ * processing can be stopped.
*/
lttv_process_traceset_begin(tsc,
NULL, NULL, NULL, event_viewer_data->event_hooks, NULL);
+
+ event_viewer_data->num_events = 0;
lttv_process_traceset_middle(tsc, ltt_time_infinite, G_MAXUINT, NULL);
gdk_x11_get_server_time(
gtk_widget_get_parent_window(event_viewer_data->tree_v));
+ lttvwindow_events_request_enable();
+
return;
}
LttvTracefileState *tfs = (LttvTracefileState*)call_data;
LttEvent *e = ltt_tracefile_get_event(tfc->tf);
+ if(event_viewer_data->num_events % CHECK_GDK_INTERVAL == 0) {
+ gtk_main_iteration_do(FALSE);
+ if(event_viewer_data->tab->stop_foreground)
+ return TRUE;
+ }
+ event_viewer_data->num_events++;
+
LttvFilter *filter = event_viewer_data->main_win_filter;
if(filter != NULL && filter->head != NULL)
if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
get_events(event_viewer_data->vadjust_c->value, event_viewer_data);
+ return 0;
}
void gui_events_free(EventViewerData *event_viewer_data)