#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"
#endif
#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);
static void tree_v_cursor_changed_cb (GtkWidget *widget, gpointer data);
static void tree_v_move_cursor_cb (GtkWidget *widget, GtkMovementStep arg1,
gint arg2, gpointer data);
+static gboolean tree_v_scroll_handler (GtkWidget *widget, GdkEventScroll *event, gpointer data);
static gboolean key_handler(GtkWidget *widget, GdkEventKey *event,
gpointer user_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);
G_CALLBACK(key_handler),
event_viewer_data);
+ g_signal_connect (G_OBJECT(event_viewer_data->tree_v), "scroll-event",
+ G_CALLBACK(tree_v_scroll_handler),
+ event_viewer_data);
+
// Use on each column!
//gtk_tree_view_column_set_sizing(event_viewer_data->tree_v,
//GTK_TREE_VIEW_COLUMN_FIXED);
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.
*/
if(lttvwindow_events_request_pending(event_viewer_data->tab)) return;
/* If no prior position... */
+#if 0
if(ltt_time_compare(
lttv_traceset_context_position_get_time(
event_viewer_data->currently_selected_position),
return;
}
-
+#endif //0
g_debug("tree view move cursor : arg1 is %u and arg2 is %d",
(guint)arg1, arg2);
/* Must get down one event and select the last one */
gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(
GTK_TREE_VIEW(event_viewer_data->tree_v)));
- event_viewer_data->update_cursor = FALSE;
- gtk_adjustment_set_value(event_viewer_data->vadjust_c,
- gtk_adjustment_get_value(event_viewer_data->vadjust_c) + 1);
- event_viewer_data->update_cursor = TRUE;
- path = gtk_tree_path_new_from_indices(
- event_viewer_data->pos->len - 1, -1);
- gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
- path, NULL, FALSE);
- gtk_tree_path_free(path);
- }
- }
+ event_viewer_data->update_cursor = FALSE;
+ gtk_adjustment_set_value(event_viewer_data->vadjust_c,
+ gtk_adjustment_get_value(event_viewer_data->vadjust_c) + 1);
+ event_viewer_data->update_cursor = TRUE;
+ if(event_viewer_data->pos->len > 0) {
+ path = gtk_tree_path_new_from_indices(
+ max(0, event_viewer_data->pos->len - 1), -1);
+ if(path) {
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+ path, NULL, FALSE);
+ gtk_tree_path_free(path);
+ }
+ }
+ }
+ } else {
+ /* Must get down one event and select the last one */
+ gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(
+ GTK_TREE_VIEW(event_viewer_data->tree_v)));
+ event_viewer_data->update_cursor = FALSE;
+ gtk_adjustment_set_value(event_viewer_data->vadjust_c,
+ gtk_adjustment_get_value(event_viewer_data->vadjust_c) + 1);
+ event_viewer_data->update_cursor = TRUE;
+ if(event_viewer_data->pos->len > 0) {
+ path = gtk_tree_path_new_from_indices(
+ max(0, event_viewer_data->pos->len - 1), -1);
+ if(path) {
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+ path, NULL, FALSE);
+ gtk_tree_path_free(path);
+ }
+ }
+ }
} else {
if(event_viewer_data->pos->len > 0) {
/* Must get up one event and select the first one */
gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(
GTK_TREE_VIEW(event_viewer_data->tree_v)));
- event_viewer_data->update_cursor = FALSE;
- gtk_adjustment_set_value(event_viewer_data->vadjust_c,
- gtk_adjustment_get_value(event_viewer_data->vadjust_c) - 1);
- event_viewer_data->update_cursor = TRUE;
- path = gtk_tree_path_new_from_indices(
- 0, -1);
- gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
- path, NULL, FALSE);
- gtk_tree_path_free(path);
- }
- }
+ event_viewer_data->update_cursor = FALSE;
+ gtk_adjustment_set_value(event_viewer_data->vadjust_c,
+ gtk_adjustment_get_value(event_viewer_data->vadjust_c) - 1);
+ event_viewer_data->update_cursor = TRUE;
+ if(event_viewer_data->pos->len > 0) {
+ path = gtk_tree_path_new_from_indices(
+ 0, -1);
+ if(path) {
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+ path, NULL, FALSE);
+ gtk_tree_path_free(path);
+ }
+ }
+ }
+ } else {
+ /* Must get up one event and select the first one */
+ gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(
+ GTK_TREE_VIEW(event_viewer_data->tree_v)));
+ event_viewer_data->update_cursor = FALSE;
+ gtk_adjustment_set_value(event_viewer_data->vadjust_c,
+ gtk_adjustment_get_value(event_viewer_data->vadjust_c) - 1);
+ event_viewer_data->update_cursor = TRUE;
+ if(event_viewer_data->pos->len > 0) {
+ path = gtk_tree_path_new_from_indices(
+ 0, -1);
+ if(path) {
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+ path, NULL, FALSE);
+ gtk_tree_path_free(path);
+ }
+ }
+ }
}
break;
case GTK_MOVEMENT_PAGES:
/* Must get down one page and select the last one */
gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(
GTK_TREE_VIEW(event_viewer_data->tree_v)));
-
- event_viewer_data->update_cursor = FALSE;
- gtk_adjustment_set_value(event_viewer_data->vadjust_c,
- gtk_adjustment_get_value(event_viewer_data->vadjust_c) + 2);
- event_viewer_data->update_cursor = TRUE;
-
- path = gtk_tree_path_new_from_indices(
- event_viewer_data->pos->len - 1, -1);
- gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
- path, NULL, FALSE);
- gtk_tree_path_free(path);
-
- }
- }
-
+ event_viewer_data->update_cursor = FALSE;
+ gtk_adjustment_set_value(event_viewer_data->vadjust_c,
+ gtk_adjustment_get_value(event_viewer_data->vadjust_c) + 2);
+ event_viewer_data->update_cursor = TRUE;
+ if(event_viewer_data->pos->len > 0) {
+ path = gtk_tree_path_new_from_indices(
+ event_viewer_data->pos->len - 1, -1);
+ if(path) {
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+ path, NULL, FALSE);
+ gtk_tree_path_free(path);
+ }
+ }
+ }
+ } else {
+ /* Must get down one page and select the last one */
+ gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(
+ GTK_TREE_VIEW(event_viewer_data->tree_v)));
+ event_viewer_data->update_cursor = FALSE;
+ gtk_adjustment_set_value(event_viewer_data->vadjust_c,
+ gtk_adjustment_get_value(event_viewer_data->vadjust_c) + 2);
+ event_viewer_data->update_cursor = TRUE;
+ if(event_viewer_data->pos->len > 0) {
+ path = gtk_tree_path_new_from_indices(
+ event_viewer_data->pos->len - 1, -1);
+ if(path) {
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+ path, NULL, FALSE);
+ gtk_tree_path_free(path);
+ }
+ }
+ }
} else {
/* Move one page up */
if(event_viewer_data->pos->len > 0) {
/* Must get up one page and select the first one */
gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(
GTK_TREE_VIEW(event_viewer_data->tree_v)));
-
- event_viewer_data->update_cursor = FALSE;
- gtk_adjustment_set_value(event_viewer_data->vadjust_c,
- gtk_adjustment_get_value(event_viewer_data->vadjust_c) - 2);
- event_viewer_data->update_cursor = TRUE;
-
- path = gtk_tree_path_new_from_indices(
- 0, -1);
- gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
- path, NULL, FALSE);
- gtk_tree_path_free(path);
- }
- }
-
+ event_viewer_data->update_cursor = FALSE;
+ gtk_adjustment_set_value(event_viewer_data->vadjust_c,
+ gtk_adjustment_get_value(event_viewer_data->vadjust_c) - 2);
+ event_viewer_data->update_cursor = TRUE;
+ if(event_viewer_data->pos->len > 0) {
+ path = gtk_tree_path_new_from_indices(
+ 0, -1);
+ if(path) {
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+ path, NULL, FALSE);
+ gtk_tree_path_free(path);
+ }
+ }
+ }
+ } else {
+ /* Must get up one page and select the first one */
+ gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(
+ GTK_TREE_VIEW(event_viewer_data->tree_v)));
+ event_viewer_data->update_cursor = FALSE;
+ gtk_adjustment_set_value(event_viewer_data->vadjust_c,
+ gtk_adjustment_get_value(event_viewer_data->vadjust_c) - 2);
+ event_viewer_data->update_cursor = TRUE;
+ if(event_viewer_data->pos->len > 0) {
+ path = gtk_tree_path_new_from_indices(
+ 0, -1);
+ if(path) {
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+ path, NULL, FALSE);
+ gtk_tree_path_free(path);
+ }
+ }
+ }
}
break;
default:
#endif //0
}
+
+gboolean tree_v_scroll_handler (GtkWidget *widget, GdkEventScroll *event, gpointer data)
+{
+ EventViewerData *event_viewer_data = (EventViewerData*) data;
+ Tab *tab = event_viewer_data->tab;
+
+ switch(event->direction) {
+ case GDK_SCROLL_UP:
+ gtk_adjustment_set_value(event_viewer_data->vadjust_c,
+ gtk_adjustment_get_value(event_viewer_data->vadjust_c) - 1);
+ break;
+ case GDK_SCROLL_DOWN:
+ 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;
+}
+
void tree_v_cursor_changed_cb (GtkWidget *widget, gpointer data)
{
EventViewerData *event_viewer_data = (EventViewerData*) data;
/* On cursor change, modify the currently selected event by calling
* the right API function */
-
-
if(event_viewer_data->report_position) {
- gtk_tree_view_get_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
- &path, NULL);
- if(gtk_tree_model_get_iter(model,&iter,path)){
- gtk_tree_model_get(model, &iter, POSITION_COLUMN, &pos, -1);
-
- if(lttv_traceset_context_pos_pos_compare(pos,
- event_viewer_data->currently_selected_position) != 0)
- lttvwindow_report_current_position(tab, pos);
- }else{
- g_warning("Can not get iter\n");
- }
- gtk_tree_path_free(path);
- }
+ if(event_viewer_data->pos->len > 0) {
+ gtk_tree_view_get_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+ &path, NULL);
+ if(path) {
+ if(gtk_tree_model_get_iter(model,&iter,path)){
+ gtk_tree_model_get(model, &iter, POSITION_COLUMN, &pos, -1);
+
+ if(lttv_traceset_context_pos_pos_compare(pos,
+ event_viewer_data->currently_selected_position) != 0)
+ lttvwindow_report_current_position(tab, pos);
+ }else{
+ g_warning("Can not get iter\n");
+ }
+ gtk_tree_path_free(path);
+ }
+ }
+ }
}
gtk_tree_view_column_cell_get_size(column, NULL, NULL, NULL, NULL, &height);
+ gint vertical_separator;
+ gtk_widget_style_get (GTK_WIDGET (TreeView),
+ "vertical-separator", &vertical_separator,
+ NULL);
+
+ height += vertical_separator;
+
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;
}
{
EventViewerData *event_viewer_data = (EventViewerData*)hook_data;
LttvTracefileContext *tfc = (LttvTracefileContext*)call_data;
+ 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,
LttFacility *facility = ltt_event_facility(e);
LttEventType *event_type = ltt_event_eventtype(e);
- LttField *field = ltt_event_field(e);
LttTime time = ltt_event_time(e);
- guint cpu = ltt_tracefile_num(tfc->tf);
+ guint cpu = tfs->cpu;
LttvTraceState *ts = (LttvTraceState*)tfc->t_context;
LttvProcessState *process = ts->running_process[cpu];
lttv_traceset_context_position_save(tfc->t_context->ts_context, pos);
- if(field)
- lttv_print_field(e, field, desc, TRUE);
+ lttv_event_to_string(e, desc, TRUE, TRUE, (LttvTracefileState*)tfc);
- g_info("field : %s", desc->str);
+ g_info("detail : %s", desc->str);
gtk_list_store_append (event_viewer_data->store_m, &iter);
gtk_list_store_set (event_viewer_data->store_m, &iter,
event_viewer_data->currently_selected_position) == 0) {
GtkTreePath *path = gtk_tree_path_new_from_indices(
event_viewer_data->pos->len - 1, -1);
- gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
- path, NULL, FALSE);
- gtk_tree_path_free(path);
+ if(path) {
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+ path, NULL, FALSE);
+ gtk_tree_path_free(path);
+ }
}
}
if(lttv_traceset_context_pos_pos_compare(cur_pos,
event_viewer_data->currently_selected_position) == 0) {
GtkTreePath *path = gtk_tree_path_new_from_indices(i, -1);
- gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
- path, NULL, FALSE);
- gtk_tree_path_free(path);
+ if(path) {
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+ path, NULL, FALSE);
+ gtk_tree_path_free(path);
+ }
}
}
}
get_events(event_viewer_data->vadjust_c->value, event_viewer_data);
// event_viewer_data->vadjust_c->value = 0;
+ request_background_data(event_viewer_data);
+
return FALSE;
}
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)