Add per list filter
[lttv.git] / ltt / branches / poly / lttv / modules / gui / detailedevents / events.c
index 51d51aa13f9990b5cb27e49615aba7feda9d7ec5..2e123ad6ea4b0388bad64df41fa46a268e59bc64 100644 (file)
@@ -1,5 +1,6 @@
 /* This file is part of the Linux Trace Toolkit viewer
  * Copyright (C) 2003-2004 Mathieu Desnoyers and XangXiu Yang
+ *               2005 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
  * 
  * This plugin adds a Events Viewer functionnality to Linux TraceToolkit
  * GUI when this plugin is loaded. The init and destroy functions add the
- * viewer's insertion menu item and toolbar icon by calling gtkTraceSet's
+ * viewer's insertion menu item and toolbar icon by calling viewer.h's
  * API functions. Then, when a viewer's object is created, the constructor
  * creates ans register through API functions what is needed to interact
- * with the TraceSet window.
+ * with the lttvwindow.
  *
  * Authors : Mathieu Desnoyers and XangXiu Yang, June to December 2003
  *           Inspired from original LTT, made by Karim Yaghmour
+ *
+ *           Mostly rewritten by Mathieu Desnoyers, August 2005.
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <math.h>
 
 #include <glib.h>
 #include <gtk/gtk.h>
 #include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#include <string.h>
 
-#include <lttv/module.h>
-#include <lttv/hook.h>
-#include <lttv/gtktraceset.h>
-#include <lttv/tracecontext.h>
-#include <lttv/state.h>
 #include <ltt/ltt.h>
 #include <ltt/event.h>
 #include <ltt/type.h>
 #include <ltt/trace.h>
 #include <ltt/facility.h>
-#include <string.h>
+#include <lttv/module.h>
+#include <lttv/hook.h>
+#include <lttv/tracecontext.h>
+#include <lttv/state.h>
+#include <lttv/filter.h>
+#include <lttv/print.h>
+#include <lttvwindow/lttvwindow.h>
+#include <lttvwindow/lttvwindowtraces.h>
+#include <lttvwindow/lttv_plugin_tab.h>
+#include <lttvwindow/support.h>
+#include "lttv_plugin_evd.h"
 
-//#include "mw_api.h"
-#include "gtktreeprivate.h"
+#include "events.h"
+#include "hGuiEventsInsert.xpm"
 
-#include "../icons/hGuiEventsInsert.xpm"
+#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
 
+#ifndef g_debug
+#define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
+#endif
 
-static LttvHooks  *before_event;
+#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 _RawTraceData{
-  unsigned  cpu_id;
-  char * event_name;
-  LttTime time;
-  int pid;
-  unsigned entry_length;
-  char * event_description;
-  LttEventPosition *ep;
-} RawTraceData;
-
-#define RESERVE_BIG_SIZE             1000
-#define RESERVE_SMALL_SIZE           100
-#define RESERVE_SMALL_SIZE_SQUARE    RESERVE_SMALL_SIZE*RESERVE_SMALL_SIZE
-#define RESERVE_SMALL_SIZE_CUBE      RESERVE_SMALL_SIZE*RESERVE_SMALL_SIZE_SQUARE
-
 typedef enum _ScrollDirection{
   SCROLL_STEP_UP,
   SCROLL_STEP_DOWN,
@@ -90,115 +94,68 @@ typedef enum _ScrollDirection{
   SCROLL_NONE
 } ScrollDirection;
 
-typedef struct _EventViewerData {
-
-  MainWindow * mw;
-  TimeWindow   time_window;
-  LttTime      current_time;
-  LttvHooks  * before_event_hooks;
-
-  gboolean     append;                    //prepend or append item 
-  GQueue     * raw_trace_data_queue;      //buf to contain raw trace data
-  GQueue     * raw_trace_data_queue_tmp;  //tmp buf to contain raw data
-  unsigned     current_event_index;
-  double       previous_value;            //value of the slide
-  TimeInterval time_span;
-  unsigned     start_event_index;        //the first event shown in the window
-  unsigned     end_event_index;          //the last event shown in the window
-  unsigned     size;                     //maxi number of events loaded when instance the viewer
-  gboolean     shown;                    //indicate if event detail is shown or not
-  gboolean     current_time_updated;
-  char *       filter_key;
-
-  //scroll window containing Tree View
-  GtkWidget * scroll_win;
-
-  /* Model containing list data */
-  GtkListStore *store_m;
-  
-  GtkWidget *hbox_v;
-  /* Widget to display the data in a columned list */
-  GtkWidget *tree_v;
-  GtkAdjustment *vtree_adjust_c ;
-  
-  /* Vertical scrollbar and it's adjustment */
-  GtkWidget *vscroll_vc;
-  GtkAdjustment *vadjust_c ;
-  
-  /* Selection handler */
-  GtkTreeSelection *select_c;
-  
-  guint num_visible_events;
-  guint first_event, last_event;
-  
-  /* TEST DATA, TO BE READ FROM THE TRACE */
-  gint number_of_events ;
-  guint currently_selected_event  ;
-  gboolean selected_event ;
-
-} EventViewerData ;
-
 /** hook functions for update time interval, current time ... */
-gboolean update_time_window(void * hook_data, void * call_data);
 gboolean update_current_time(void * hook_data, void * call_data);
-gboolean show_event_detail(void * hook_data, void * call_data);
+gboolean update_current_position(void * hook_data, void * call_data);
+//gboolean show_event_detail(void * hook_data, void * call_data);
 gboolean traceset_changed(void * hook_data, void * call_data);
-void remove_item_from_queue(GQueue * q, gboolean fromHead);
-void remove_all_items_from_queue(GQueue * q);
-void add_context_hooks(EventViewerData * event_viewer_data, 
-           LttvTracesetContext * tsc);
-void remove_context_hooks(EventViewerData * event_viewer_data, 
-        LttvTracesetContext * tsc);
+gboolean filter_changed(void * hook_data, void * call_data);
+
+static void request_background_data(EventViewerData *event_viewer_data);
 
 //! Event Viewer's constructor hook
-GtkWidget *h_gui_events(MainWindow *parent_window, LttvTracesetSelector * s, char* key);
+GtkWidget *h_gui_events(LttvPlugin *plugin);
 //! Event Viewer's constructor
-EventViewerData *gui_events(MainWindow *parent_window, LttvTracesetSelector *s, char *key);
+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);
+void gui_events_destructor(gpointer data);
+void gui_events_free(gpointer data);
 
-static int event_selected_hook(void *hook_data, void *call_data);
+static gboolean
+header_size_allocate(GtkWidget *widget,
+                        GtkAllocation *allocation,
+                        gpointer user_data);
 
 void tree_v_set_cursor(EventViewerData *event_viewer_data);
 void tree_v_get_cursor(EventViewerData *event_viewer_data);
 
 /* Prototype for selection handler callback */
-static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data);
+static void tree_selection_changed_cb (GtkTreeSelection *selection,
+    gpointer data);
 static void v_scroll_cb (GtkAdjustment *adjustment, gpointer data);
-static void tree_v_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer data);
-static void tree_v_size_request_cb (GtkWidget *widget, GtkRequisition *requisition, gpointer data);
+static void tree_v_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc,
+    gpointer data);
+static void tree_v_size_request_cb (GtkWidget *widget,
+    GtkRequisition *requisition, gpointer 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 void tree_v_grab_focus(GtkWidget *widget, gpointer data);
-
-
-static void get_test_data(double time, guint list_height, 
-        EventViewerData *event_viewer_data);
-
-void add_test_data(EventViewerData *event_viewer_data);
+static void tree_v_move_cursor_cb (GtkWidget *widget, GtkMovementStep arg1,
+    gint arg2, gpointer data);
+static void        filter_button      (GtkToolButton *toolbutton,
+                                          gpointer       user_data);
+static gboolean tree_v_scroll_handler (GtkWidget *widget, GdkEventScroll *event, gpointer data);
+static gboolean key_handler(GtkWidget *widget, GdkEventKey *event,
+    gpointer user_data);
 
-static void update_raw_data_array(EventViewerData* event_viewer_data, unsigned size);
+static void get_events(double time, EventViewerData *event_viewer_data);
 
-static void get_events(EventViewerData* event_viewer_data, LttTime start, 
-           LttTime end, unsigned max_num_events, unsigned * real_num_events);
-static gboolean parse_event(void *hook_data, void *call_data);
-
-static LttvModule *main_win_module;
+int event_hook(void *hook_data, void *call_data);
 
 /* Enumeration of the columns */
 enum
 {
+  TRACE_NAME_COLUMN,
+  TRACEFILE_NAME_COLUMN,
   CPUID_COLUMN,
   EVENT_COLUMN,
-  TIME_COLUMN,
+  FACILITY_COLUMN,
+  TIME_S_COLUMN,
+  TIME_NS_COLUMN,
   PID_COLUMN,
-  ENTRY_LEN_COLUMN,
   EVENT_DESCR_COLUMN,
+  POSITION_COLUMN,
   N_COLUMNS
 };
 
-
 /**
  * Event Viewer's constructor hook
  *
@@ -208,12 +165,12 @@ enum
  * @return The widget created.
  */
 GtkWidget *
-h_gui_events(MainWindow * parent_window, LttvTracesetSelector * s, char* key)
+h_gui_events(LttvPlugin *plugin)
 {
-  EventViewerData* event_viewer_data = gui_events(parent_window, s, key) ;
-
+  LttvPluginTab *ptab = LTTV_PLUGIN_TAB(plugin);
+  EventViewerData* event_viewer_data = gui_events(ptab) ;
   if(event_viewer_data)
-    return event_viewer_data->hbox_v;
+    return event_viewer_data->top_widget;
   else return NULL;
   
 }
@@ -225,50 +182,80 @@ h_gui_events(MainWindow * parent_window, LttvTracesetSelector * s, char* key)
  * @return The Event viewer data created.
  */
 EventViewerData *
-gui_events(MainWindow *parent_window, LttvTracesetSelector * s,char* key )
+gui_events(LttvPluginTab *ptab)
 {
-  LttTime start, end;
+  LttTime end;
   GtkTreeViewColumn *column;
   GtkCellRenderer *renderer;
-  EventViewerData* event_viewer_data = g_new(EventViewerData,1) ;
-  RawTraceData * data;
-
-  event_viewer_data->mw = parent_window;
-  get_time_window(event_viewer_data->mw, &event_viewer_data->time_window);
-  get_current_time(event_viewer_data->mw, &event_viewer_data->current_time);
+  EventViewerData* event_viewer_data = g_new(EventViewerData,1);
+  LttvPluginEVD *plugin_evd = g_object_new(LTTV_TYPE_PLUGIN_EVD, NULL);
+  plugin_evd->evd = event_viewer_data;
+  Tab *tab = ptab->tab;
+  event_viewer_data->tab = tab;
+  event_viewer_data->ptab = ptab;
+  GtkWidget *tmp_toolbar_icon;
+
+  LttvTracesetContext * tsc =
+        lttvwindow_get_traceset_context(event_viewer_data->tab);
+
+  
+  event_viewer_data->event_hooks = lttv_hooks_new();
+  lttv_hooks_add(event_viewer_data->event_hooks,
+                 event_hook,
+                 event_viewer_data,
+                 LTTV_PRIO_DEFAULT);
+
+  lttvwindow_register_current_time_notify(tab, 
+                update_current_time,event_viewer_data);
+  lttvwindow_register_current_position_notify(tab, 
+                update_current_position,event_viewer_data);
+  lttvwindow_register_traceset_notify(tab, 
+                traceset_changed,event_viewer_data);
+  lttvwindow_register_filter_notify(tab,
+                filter_changed, event_viewer_data);
+  lttvwindow_register_redraw_notify(tab,
+                evd_redraw_notify, event_viewer_data);
   
-  event_viewer_data->before_event_hooks = lttv_hooks_new();
-  lttv_hooks_add(event_viewer_data->before_event_hooks, parse_event, event_viewer_data);
 
-  event_viewer_data->raw_trace_data_queue     = g_queue_new();
-  event_viewer_data->raw_trace_data_queue_tmp = g_queue_new();  
+  event_viewer_data->scroll_win = gtk_scrolled_window_new (NULL, NULL);
+  gtk_widget_show (event_viewer_data->scroll_win);
+  gtk_scrolled_window_set_policy(
+      GTK_SCROLLED_WINDOW(event_viewer_data->scroll_win), 
+      GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
+
+  event_viewer_data->currently_selected_position =
+    lttv_traceset_context_position_new(tsc);
+  event_viewer_data->first_event =
+    lttv_traceset_context_position_new(tsc);
+  event_viewer_data->last_event =
+    lttv_traceset_context_position_new(tsc);
 
-  reg_update_time_window(update_time_window,event_viewer_data, event_viewer_data->mw);
-  reg_update_current_time(update_current_time,event_viewer_data, event_viewer_data->mw);
-  reg_show_viewer(show_event_detail,event_viewer_data, event_viewer_data->mw);
-  reg_update_traceset(traceset_changed,event_viewer_data, event_viewer_data->mw);
+  event_viewer_data->main_win_filter = lttvwindow_get_filter(tab);
 
-  event_viewer_data->scroll_win = gtk_scrolled_window_new (NULL, NULL);
-  gtk_widget_show ( event_viewer_data->scroll_win);
-  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(event_viewer_data->scroll_win), 
-         GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
+  event_viewer_data->update_cursor = TRUE;
+  event_viewer_data->report_position = TRUE;
 
-  /* TEST DATA, TO BE READ FROM THE TRACE */
-  event_viewer_data->currently_selected_event = FALSE  ;
-  event_viewer_data->selected_event = 0;
+  event_viewer_data->last_tree_update_time = 0;
 
   /* Create a model for storing the data list */
   event_viewer_data->store_m = gtk_list_store_new (
-    N_COLUMNS,  /* Total number of columns */
-    G_TYPE_INT, /* CPUID                  */
-    G_TYPE_STRING,  /* Event                   */
-    G_TYPE_UINT64,  /* Time                    */
-    G_TYPE_INT, /* PID                     */
-    G_TYPE_INT, /* Entry length            */
-    G_TYPE_STRING); /* Event's description     */
+    N_COLUMNS,      /* Total number of columns     */
+    G_TYPE_STRING,  /* Trace name                  */
+    G_TYPE_STRING,  /* Tracefile name              */
+    G_TYPE_UINT,    /* CPUID                       */
+    G_TYPE_STRING,  /* Event                       */
+    G_TYPE_STRING,  /* Facility                    */
+    G_TYPE_UINT,    /* Time s                      */
+    G_TYPE_UINT,    /* Time ns                     */
+    G_TYPE_INT,     /* PID                         */
+    G_TYPE_STRING,  /* Event's description         */
+    G_TYPE_POINTER);/* Position (not shown)        */
+  
+  event_viewer_data->pos = g_ptr_array_sized_new(10);
   
   /* Create the viewer widget for the columned list */
-  event_viewer_data->tree_v = gtk_tree_view_new_with_model (GTK_TREE_MODEL (event_viewer_data->store_m));
+  event_viewer_data->tree_v =
+    gtk_tree_view_new_with_model (GTK_TREE_MODEL (event_viewer_data->store_m));
     
   g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "size-allocate",
         G_CALLBACK (tree_v_size_allocate_cb),
@@ -285,12 +272,19 @@ gui_events(MainWindow *parent_window, LttvTracesetSelector * s,char* key )
         G_CALLBACK (tree_v_move_cursor_cb),
         event_viewer_data);
 
-  g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "grab-focus",
-        G_CALLBACK (tree_v_grab_focus),
-        event_viewer_data);
-    
+  g_signal_connect (G_OBJECT(event_viewer_data->tree_v), "key-press-event",
+      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);
+  //gtk_tree_view_column_set_sizing(event_viewer_data->tree_v,
+  //GTK_TREE_VIEW_COLUMN_FIXED);
   
   /* The view now holds a reference.  We can get rid of our own
    * reference */
@@ -300,6 +294,36 @@ gui_events(MainWindow *parent_window, LttvTracesetSelector * s,char* key )
   /* Create a column, associating the "text" attribute of the
    * cell_renderer to the first column of the model */
   /* Columns alignment : 0.0 : Left    0.5 : Center   1.0 : Right */
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("Trace",
+                 renderer,
+                 "text", TRACE_NAME_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 0.0);
+  gtk_tree_view_column_set_fixed_width (column, 120);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
+      column);
+
+  event_viewer_data->button = column->button;
+
+  g_signal_connect (G_OBJECT(event_viewer_data->button),
+        "size-allocate",
+        G_CALLBACK(header_size_allocate),
+        (gpointer)event_viewer_data);
+
+
+  
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("Tracefile",
+                 renderer,
+                 "text", TRACEFILE_NAME_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 0.0);
+  gtk_tree_view_column_set_fixed_width (column, 120);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
+      column);
+
+
   renderer = gtk_cell_renderer_text_new ();
   column = gtk_tree_view_column_new_with_attributes ("CPUID",
                  renderer,
@@ -307,7 +331,8 @@ gui_events(MainWindow *parent_window, LttvTracesetSelector * s,char* key )
                  NULL);
   gtk_tree_view_column_set_alignment (column, 0.0);
   gtk_tree_view_column_set_fixed_width (column, 45);
-  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
+      column);
 
   renderer = gtk_cell_renderer_text_new ();
   column = gtk_tree_view_column_new_with_attributes ("Event",
@@ -316,55 +341,102 @@ gui_events(MainWindow *parent_window, LttvTracesetSelector * s,char* key )
                  NULL);
   gtk_tree_view_column_set_alignment (column, 0.0);
   gtk_tree_view_column_set_fixed_width (column, 120);
-  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column);
-
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
+      column);
+  
   renderer = gtk_cell_renderer_text_new ();
-  column = gtk_tree_view_column_new_with_attributes ("Time",
+  column = gtk_tree_view_column_new_with_attributes ("Facility",
                  renderer,
-                 "text", TIME_COLUMN,
+                 "text", FACILITY_COLUMN,
                  NULL);
-  gtk_tree_view_column_set_alignment (column, 1.0);
+  gtk_tree_view_column_set_alignment (column, 0.0);
   gtk_tree_view_column_set_fixed_width (column, 120);
-  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
+      column);
 
   renderer = gtk_cell_renderer_text_new ();
-  column = gtk_tree_view_column_new_with_attributes ("PID",
+  column = gtk_tree_view_column_new_with_attributes ("Time (s)",
                  renderer,
-                 "text", PID_COLUMN,
+                 "text", TIME_S_COLUMN,
                  NULL);
   gtk_tree_view_column_set_alignment (column, 1.0);
-  gtk_tree_view_column_set_fixed_width (column, 45);
-  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column);
+  gtk_tree_view_column_set_fixed_width (column, 120);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
+      column);
   
   renderer = gtk_cell_renderer_text_new ();
-  column = gtk_tree_view_column_new_with_attributes ("Entry Length",
+  column = gtk_tree_view_column_new_with_attributes ("Time (ns)",
+                 renderer,
+                 "text", TIME_NS_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 1.0);
+  gtk_tree_view_column_set_fixed_width (column, 120);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
+      column);
+
+
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("PID",
                  renderer,
-                 "text", ENTRY_LEN_COLUMN,
+                 "text", PID_COLUMN,
                  NULL);
   gtk_tree_view_column_set_alignment (column, 1.0);
-  gtk_tree_view_column_set_fixed_width (column, 60);
-  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column);
+  gtk_tree_view_column_set_fixed_width (column, 45);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
+      column);
   
   renderer = gtk_cell_renderer_text_new ();
-  column = gtk_tree_view_column_new_with_attributes ("Event's Description",
+  column = gtk_tree_view_column_new_with_attributes ("Event Description",
                  renderer,
                  "text", EVENT_DESCR_COLUMN,
                  NULL);
   gtk_tree_view_column_set_alignment (column, 0.0);
-  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
+      column);
 
 
   /* Setup the selection handler */
-  event_viewer_data->select_c = gtk_tree_view_get_selection (GTK_TREE_VIEW (event_viewer_data->tree_v));
-  gtk_tree_selection_set_mode (event_viewer_data->select_c, GTK_SELECTION_SINGLE);
+  event_viewer_data->select_c =
+    gtk_tree_view_get_selection (GTK_TREE_VIEW (event_viewer_data->tree_v));
+  gtk_tree_selection_set_mode (event_viewer_data->select_c,
+      GTK_SELECTION_SINGLE);
   g_signal_connect (G_OBJECT (event_viewer_data->select_c), "changed",
         G_CALLBACK (tree_selection_changed_cb),
         event_viewer_data);
   
-  gtk_container_add (GTK_CONTAINER (event_viewer_data->scroll_win), event_viewer_data->tree_v);
+  gtk_container_add (GTK_CONTAINER (event_viewer_data->scroll_win),
+      event_viewer_data->tree_v);
 
   event_viewer_data->hbox_v = gtk_hbox_new(0, 0);
-  gtk_box_pack_start(GTK_BOX(event_viewer_data->hbox_v), event_viewer_data->scroll_win, TRUE, TRUE, 0);
+  event_viewer_data->top_widget = event_viewer_data->hbox_v;
+  plugin_evd->parent.top_widget = event_viewer_data->hbox_v;
+
+  event_viewer_data->toolbar = gtk_toolbar_new();
+  gtk_toolbar_set_orientation(GTK_TOOLBAR(event_viewer_data->toolbar),
+                              GTK_ORIENTATION_VERTICAL);
+
+  tmp_toolbar_icon = create_pixmap (main_window_get_widget(tab),
+      "guifilter16x16.png");
+  gtk_widget_show(tmp_toolbar_icon);
+  event_viewer_data->button_filter = gtk_tool_button_new(tmp_toolbar_icon,
+      "Filter");
+  g_signal_connect (G_OBJECT(event_viewer_data->button_filter),
+        "clicked",
+        G_CALLBACK (filter_button),
+        (gpointer)plugin_evd);
+  gtk_toolbar_insert(GTK_TOOLBAR(event_viewer_data->toolbar),
+      event_viewer_data->button_filter,
+      0);
+  gtk_toolbar_set_style(GTK_TOOLBAR(event_viewer_data->toolbar),
+      GTK_TOOLBAR_ICONS);
+  gtk_box_pack_start(GTK_BOX(event_viewer_data->hbox_v),
+      event_viewer_data->toolbar, FALSE, FALSE, 0);
+  event_viewer_data->filter = NULL;
+
+  gtk_box_pack_start(GTK_BOX(event_viewer_data->hbox_v),
+      event_viewer_data->scroll_win, TRUE, TRUE, 0);
+
+  gtk_container_set_border_width(GTK_CONTAINER(event_viewer_data->hbox_v), 1);
 
   /* Create vertical scrollbar and pack it */
   event_viewer_data->vscroll_vc = gtk_vscrollbar_new(NULL);
@@ -372,10 +444,12 @@ gui_events(MainWindow *parent_window, LttvTracesetSelector * s,char* key )
              GTK_UPDATE_CONTINUOUS);
              // Changed by MD : more user friendly :)
              //GTK_UPDATE_DISCONTINUOUS);
-  gtk_box_pack_start(GTK_BOX(event_viewer_data->hbox_v), event_viewer_data->vscroll_vc, FALSE, TRUE, 0);
+  gtk_box_pack_start(GTK_BOX(event_viewer_data->hbox_v),
+      event_viewer_data->vscroll_vc, FALSE, TRUE, 0);
   
   /* Get the vertical scrollbar's adjustment */
-  event_viewer_data->vadjust_c = gtk_range_get_adjustment(GTK_RANGE(event_viewer_data->vscroll_vc));
+  event_viewer_data->vadjust_c =
+    gtk_range_get_adjustment(GTK_RANGE(event_viewer_data->vscroll_vc));
   event_viewer_data->vtree_adjust_c = gtk_tree_view_get_vadjustment(
                     GTK_TREE_VIEW (event_viewer_data->tree_v));
   
@@ -393,77 +467,159 @@ gui_events(MainWindow *parent_window, LttvTracesetSelector * s,char* key )
   event_viewer_data->vadjust_c->page_size = 2.0;
   //    event_viewer_data->vtree_adjust_c->upper;
   /*  Raw event trace */
+  gtk_widget_show(GTK_WIDGET(event_viewer_data->button_filter));
+  gtk_widget_show(event_viewer_data->toolbar);
   gtk_widget_show(event_viewer_data->hbox_v);
   gtk_widget_show(event_viewer_data->tree_v);
   gtk_widget_show(event_viewer_data->vscroll_vc);
 
   /* Add the object's information to the module's array */
-  g_event_viewer_data_list = g_slist_append(g_event_viewer_data_list, event_viewer_data);
+  g_event_viewer_data_list = g_slist_append(g_event_viewer_data_list,
+      plugin_evd);
 
-  event_viewer_data->first_event = -1 ;
-  event_viewer_data->last_event = 0 ;
-  
   event_viewer_data->num_visible_events = 1;
 
   //get the life span of the traceset and set the upper of the scroll bar
-  get_traceset_time_span(event_viewer_data->mw, &event_viewer_data->time_span);
   
-  start = ltt_time_sub(event_viewer_data->time_span.endTime, event_viewer_data->time_span.startTime);
-  event_viewer_data->vadjust_c->upper = ltt_time_to_double(start) * NANOSECONDS_PER_SECOND;
-
-  event_viewer_data->append = TRUE;
+  TimeInterval time_span = tsc->time_span;
+  end = ltt_time_sub(time_span.end_time, time_span.start_time);
 
-  event_viewer_data->start_event_index = 0;
-  event_viewer_data->end_event_index   = event_viewer_data->num_visible_events - 1;  
+  event_viewer_data->vadjust_c->upper =
+              ltt_time_to_double(end);
 
   /* Set the Selected Event */
   //  tree_v_set_cursor(event_viewer_data);
 
-  event_viewer_data->shown = FALSE;
-  event_viewer_data->current_time_updated = FALSE;
-  event_viewer_data->size  = RESERVE_SMALL_SIZE;
-  g_object_set_data(
-        G_OBJECT(event_viewer_data->hbox_v),
-        MAX_NUMBER_EVENT,
-        &event_viewer_data->size);
-/*  
-  g_object_set_data(
-        G_OBJECT(event_viewer_data->hbox_v),
-        TRACESET_TIME_SPAN,
-        &event_viewer_data->time_span);
-*/
-  event_viewer_data->filter_key = g_strdup(key);
-  g_object_set_data(
-        G_OBJECT(event_viewer_data->hbox_v),
-        event_viewer_data->filter_key,
-        s);
-  
+ // event_viewer_data->current_time_updated = FALSE;
+ //
   g_object_set_data_full(
       G_OBJECT(event_viewer_data->hbox_v),
-      "event_viewer_data",
-      event_viewer_data,
+      "plugin_data",
+      plugin_evd,
       (GDestroyNotify)gui_events_free);
+
+  g_object_set_data(
+      G_OBJECT(event_viewer_data->hbox_v),
+      "event_viewer_data",
+      event_viewer_data);
+  
+  event_viewer_data->background_info_waiting = 0;
+
+  request_background_data(event_viewer_data);
   
+
   return event_viewer_data;
 }
 
+
+
+static gint background_ready(void *hook_data, void *call_data)
+{
+  EventViewerData *event_viewer_data = (EventViewerData *)hook_data;
+  LttvTrace *trace = (LttvTrace*)call_data;
+
+  event_viewer_data->background_info_waiting--;
+
+  if(event_viewer_data->background_info_waiting == 0) {
+    g_message("event viewer : background computation data ready.");
+
+    evd_redraw_notify(event_viewer_data, NULL);
+  }
+
+  return 0;
+}
+
+
+static void request_background_data(EventViewerData *event_viewer_data)
+{
+  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();
+  lttv_hooks_add(background_ready_hook, background_ready, event_viewer_data,
+      LTTV_PRIO_DEFAULT);
+  event_viewer_data->background_info_waiting = 0;
+  
+  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
+        && !tstate->has_precomputed_states) {
+
+      if(lttvwindowtraces_get_in_progress(g_quark_from_string("state"),
+                                          trace) == FALSE) {
+        /* We first remove requests that could have been done for the same
+         * information. Happens when two viewers ask for it before servicing
+         * starts.
+         */
+        if(!lttvwindowtraces_background_request_find(trace, "state"))
+          lttvwindowtraces_background_request_queue(
+              main_window_get_widget(event_viewer_data->tab), trace, "state");
+        lttvwindowtraces_background_notify_queue(event_viewer_data,
+                                                 trace,
+                                                 ltt_time_infinite,
+                                                 NULL,
+                                                 background_ready_hook);
+        event_viewer_data->background_info_waiting++;
+      } else { /* in progress */
+      
+        lttvwindowtraces_background_notify_current(event_viewer_data,
+                                                   trace,
+                                                   ltt_time_infinite,
+                                                   NULL,
+                                                   background_ready_hook);
+        event_viewer_data->background_info_waiting++;
+      }
+    } else {
+      /* 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.
+       */
+    }
+    
+  }
+
+  lttv_hooks_destroy(background_ready_hook);
+
+}
+
+static gboolean
+header_size_allocate(GtkWidget *widget,
+                        GtkAllocation *allocation,
+                        gpointer user_data)
+{
+  EventViewerData *event_viewer_data = (EventViewerData*)user_data;
+
+  event_viewer_data->header_height = allocation->height;
+
+  return 0;
+}
+
+
 void tree_v_set_cursor(EventViewerData *event_viewer_data)
 {
   GtkTreePath *path;
   
-  if(event_viewer_data->selected_event && event_viewer_data->first_event != -1)
+  g_debug("set cursor cb");
+
+#if 0
+  if(event_viewer_data->currently_selected_event != -1)
     {
-      //      gtk_adjustment_set_value(event_viewer_data->vadjust_c,
-     //            event_viewer_data->currently_selected_event);
-      
       path = gtk_tree_path_new_from_indices(
-              event_viewer_data->currently_selected_event-
-              event_viewer_data->first_event,
+              event_viewer_data->currently_selected_event,
               -1);
       
-      gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
+      gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+          path, NULL, FALSE);
       gtk_tree_path_free(path);
     }
+#endif //0
 }
 
 void tree_v_get_cursor(EventViewerData *event_viewer_data)
@@ -471,95 +627,327 @@ void tree_v_get_cursor(EventViewerData *event_viewer_data)
   GtkTreePath *path;
   gint *indices;
   
-  gtk_tree_view_get_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), &path, NULL);
+  g_debug("get cursor cb");
+  
+
+#if 0
+  gtk_tree_view_get_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+      &path, NULL);
   indices = gtk_tree_path_get_indices(path);
   
   if(indices != NULL)
-    {
-      event_viewer_data->selected_event = TRUE;
-      event_viewer_data->currently_selected_event =
-  event_viewer_data->first_event + indices[0];
-      
-    } else {
-      event_viewer_data->selected_event = FALSE;
-      event_viewer_data->currently_selected_event = 0;
-    }
+      event_viewer_data->currently_selected_event = indices[0];
+    else
+      event_viewer_data->currently_selected_event = -1;
   
   gtk_tree_path_free(path);
-
+#endif //0
 }
 
+/* Filter out the key repeats that come too fast */
+static gboolean key_handler(GtkWidget *widget, GdkEventKey *event,
+    gpointer user_data)
+{
+  EventViewerData *evd = (EventViewerData *)user_data;
+  g_debug("event time : %u , last time : %u", event->time,
+      evd->last_tree_update_time);
+  
+  if(guint32_before(event->time, evd->last_tree_update_time))
+    return TRUE;
+  else
+    return FALSE;
+}
 
-
-void tree_v_move_cursor_cb (GtkWidget *widget, GtkMovementStep arg1, gint arg2, gpointer data)
+void tree_v_move_cursor_cb (GtkWidget *widget,
+                            GtkMovementStep arg1,
+                            gint arg2,
+                            gpointer data)
 {
   GtkTreePath *path; // = gtk_tree_path_new();
   gint *indices;
   gdouble value;
   EventViewerData *event_viewer_data = (EventViewerData*)data;
   
-  gtk_tree_view_get_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), &path, NULL);
-  if(path == NULL)
-    {
-      /* No prior cursor, put it at beginning of page and let the execution do */
-      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);
-    }
-  
-  indices = gtk_tree_path_get_indices(path);
+  g_debug("move cursor cb");
+  //gtk_tree_view_get_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+  //                          &path, NULL);
+  //if(path == NULL)
+  //{
+    /* No prior cursor, put it at beginning of page
+     * and let the execution do */
+  //  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);
+  //}
+
+  //indices = gtk_tree_path_get_indices(path);
   
-  value = gtk_adjustment_get_value(event_viewer_data->vadjust_c);
+  //value = gtk_adjustment_get_value(event_viewer_data->vadjust_c);
+  /* If events request pending, do nothing*/
+  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),
+        ltt_time_infinite) == 0) {
+    
+    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);
+    return;
+
+  }
+#endif //0
+  
+  g_debug("tree view move cursor : arg1 is %u and arg2 is %d",
+      (guint)arg1, arg2);
+
+  switch(arg1) {
+  case GTK_MOVEMENT_DISPLAY_LINES:
+    if(arg2 == 1) {
+      /* Move one line down */
+      if(event_viewer_data->pos->len > 0) {
+        LttvTracesetContextPosition *end_pos = 
+          (LttvTracesetContextPosition*)g_ptr_array_index(
+                                             event_viewer_data->pos,
+                                             event_viewer_data->pos->len-1);
+        if(lttv_traceset_context_pos_pos_compare(end_pos, 
+              event_viewer_data->currently_selected_position) == 0) {
+          /* 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 {
+                               /* 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) {
+        /* Move one line up */
+        LttvTracesetContextPosition *begin_pos = 
+          (LttvTracesetContextPosition*)g_ptr_array_index(
+                                             event_viewer_data->pos,
+                                             0);
+        if(lttv_traceset_context_pos_pos_compare(begin_pos, 
+              event_viewer_data->currently_selected_position) == 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;
+                                       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:
+    if(arg2 == 1) {
+      /* Move one page down */
+      if(event_viewer_data->pos->len > 0) {
+        LttvTracesetContextPosition *end_pos = 
+          (LttvTracesetContextPosition*)g_ptr_array_index(
+                                             event_viewer_data->pos,
+                                             event_viewer_data->pos->len-1);
+        if(lttv_traceset_context_pos_pos_compare(end_pos, 
+              event_viewer_data->currently_selected_position) == 0) {
+          /* 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 {
+                       /* 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) {
+        LttvTracesetContextPosition *begin_pos = 
+          (LttvTracesetContextPosition*)g_ptr_array_index(
+                                             event_viewer_data->pos,
+                                             0);
+        if(lttv_traceset_context_pos_pos_compare(begin_pos, 
+              event_viewer_data->currently_selected_position) == 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;
+                                       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:
+    break;
+  }
+
+  //gtk_tree_path_free(path);
   
+#if 0
   if(arg1 == GTK_MOVEMENT_DISPLAY_LINES)
-    {
-      /* Move one line */
-      if(arg2 == 1)
   {
-    /* move one line down */
-    if(indices[0] == event_viewer_data->num_visible_events - 1)
+    /* Move one line */
+    if(arg2 == 1)
+    {
+      /* move one line down */
+      if(indices[0]) // Do we need an empty field here (before first)?
       {
         if(value + event_viewer_data->num_visible_events <= 
-     event_viewer_data->number_of_events -1)
-    {
-      event_viewer_data->currently_selected_event += 1;
-      //      gtk_adjustment_set_value(event_viewer_data->vadjust_c, value+1);
-      //gtk_tree_path_free(path);
-      //path = gtk_tree_path_new_from_indices(event_viewer_data->num_visible_events-1, -1);
-      //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
-      g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
-    }
+            event_viewer_data->number_of_events -1)
+        {
+          event_viewer_data->currently_selected_event += 1;
+          //      gtk_adjustment_set_value(event_viewer_data->vadjust_c, value+1);
+          //gtk_tree_path_free(path);
+          //path = gtk_tree_path_new_from_indices(event_viewer_data->num_visible_events-1, -1);
+          //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
+          g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
+        }
       }
-  } else {
-    /* Move one line up */
-    if(indices[0] == 0)
+    } else {
+      /* Move one line up */
+      if(indices[0] == 0)
       {
         if(value - 1 >= 0 )
-    {
-      event_viewer_data->currently_selected_event -= 1;
-      //      gtk_adjustment_set_value(event_viewer_data->vadjust_c, value-1);
-      //gtk_tree_path_free(path);
-      //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);
-      g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
-    }
-        
+        {
+          event_viewer_data->currently_selected_event -= 1;
+          //      gtk_adjustment_set_value(event_viewer_data->vadjust_c, value-1);
+          //gtk_tree_path_free(path);
+          //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);
+          g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
+        }
       }
-  }
-      
     }
+  }
   
   if(arg1 == GTK_MOVEMENT_PAGES)
-    {
-      /* Move one page */
-      if(arg2 == 1)
   {
-    if(event_viewer_data->num_visible_events == 1)
-      value += 1 ;
-    /* move one page down */
-    if(value + event_viewer_data->num_visible_events-1 <= 
-       event_viewer_data->number_of_events )
+    /* Move one page */
+    if(arg2 == 1)
+    {
+      if(event_viewer_data->num_visible_events == 1)
+        value += 1 ;
+      /* move one page down */
+      if(value + event_viewer_data->num_visible_events-1 <= 
+                      event_viewer_data->number_of_events )
       {
-        event_viewer_data->currently_selected_event += event_viewer_data->num_visible_events-1;
+        event_viewer_data->currently_selected_event += 
+                                  event_viewer_data->num_visible_events-1;
         //        gtk_adjustment_set_value(event_viewer_data->vadjust_c,
         //               value+(event_viewer_data->num_visible_events-1));
         //gtk_tree_path_free(path);
@@ -567,142 +955,257 @@ void tree_v_move_cursor_cb (GtkWidget *widget, GtkMovementStep arg1, gint arg2,
         //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
         g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
       }
-  } else {
-    /* Move one page up */
-    if(event_viewer_data->num_visible_events == 1)
-      value -= 1 ;
+    } else {
+      /* Move one page up */
+      if(event_viewer_data->num_visible_events == 1)
+        value -= 1 ;
 
-    if(indices[0] < event_viewer_data->num_visible_events - 2 )
+      if(indices[0] < event_viewer_data->num_visible_events - 2 )
       {
         if(value - (event_viewer_data->num_visible_events-1) >= 0)
-    {
-      event_viewer_data->currently_selected_event -= event_viewer_data->num_visible_events-1;
+        {
+          event_viewer_data->currently_selected_event -=
+                          event_viewer_data->num_visible_events-1;
       
-      //      gtk_adjustment_set_value(event_viewer_data->vadjust_c,
-      //             value-(event_viewer_data->num_visible_events-1));
-      //gtk_tree_path_free(path);
-      //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);
-      g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
+          //      gtk_adjustment_set_value(event_viewer_data->vadjust_c,
+          //             value-(event_viewer_data->num_visible_events-1));
+          //gtk_tree_path_free(path);
+          //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);
+          g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
       
-    } else {
-      /* Go to first Event */
-      event_viewer_data->currently_selected_event == 0 ;
-      //      gtk_adjustment_set_value(event_viewer_data->vadjust_c,
-      //             0);
-      //gtk_tree_path_free(path);
-      //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);
-      g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
+        } else {
+          /* Go to first Event */
+          event_viewer_data->currently_selected_event == 0 ;
+          //      gtk_adjustment_set_value(event_viewer_data->vadjust_c,
+          //             0);
+          //gtk_tree_path_free(path);
+          //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);
+          g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
       
-    }
+        }
       }
-    
-  }
-      
     }
+  }
   
   if(arg1 == GTK_MOVEMENT_BUFFER_ENDS)
-    {
-      /* Move to the ends of the buffer */
-      if(arg2 == 1)
   {
-    /* move end of buffer */
-    event_viewer_data->currently_selected_event = event_viewer_data->number_of_events-1 ;
-    //    gtk_adjustment_set_value(event_viewer_data->vadjust_c, 
-    //           event_viewer_data->number_of_events -
-    //           event_viewer_data->num_visible_events);
-    //gtk_tree_path_free(path);
-    //path = gtk_tree_path_new_from_indices(event_viewer_data->num_visible_events-1, -1);
-    //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
-    g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
-  } else {
-    /* Move beginning of buffer */
-    event_viewer_data->currently_selected_event = 0 ;
-    //    gtk_adjustment_set_value(event_viewer_data->vadjust_c, 0);
+    /* Move to the ends of the buffer */
+    if(arg2 == 1)
+    {
+      /* move end of buffer */
+      event_viewer_data->currently_selected_event =
+                            event_viewer_data->number_of_events-1 ;
+      //    gtk_adjustment_set_value(event_viewer_data->vadjust_c, 
+      //           event_viewer_data->number_of_events -
+      //           event_viewer_data->num_visible_events);
       //gtk_tree_path_free(path);
-      //path = gtk_tree_path_new_from_indices(0, -1);
+      //path = gtk_tree_path_new_from_indices(event_viewer_data->num_visible_events-1, -1);
       //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
-    g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
-  }
-      
+      g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
+    } else {
+      /* Move beginning of buffer */
+      event_viewer_data->currently_selected_event = 0 ;
+      //    gtk_adjustment_set_value(event_viewer_data->vadjust_c, 0);
+        //gtk_tree_path_free(path);
+        //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);
+      g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
     }
-  
-  
-  gtk_tree_path_free(path);
+  }
+#endif //0
+}
+
+static void        filter_button      (GtkToolButton *toolbutton,
+                                          gpointer       user_data)
+{
+  LttvPluginEVD *plugin_evd = (LttvPluginEVD*)user_data;
+  LttvAttribute *attribute;
+  LttvAttributeValue value;
+  gboolean ret;
+  g_printf("Filter button clicked\n");
+
+  attribute = LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
+        LTTV_IATTRIBUTE(lttv_global_attributes()),
+        LTTV_VIEWER_CONSTRUCTORS));
+  g_assert(attribute);
+
+  ret = lttv_iattribute_find_by_path(LTTV_IATTRIBUTE(attribute),
+      "guifilter", LTTV_POINTER, &value);
+  g_assert(ret);
+  lttvwindow_viewer_constructor constructor =
+    (lttvwindow_viewer_constructor)*(value.v_pointer);
+  if(constructor) constructor(&plugin_evd->parent);
+  else g_warning("Filter module not loaded.");
+
+  //FIXME : viewer returned.
+}
+
+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;
-  LttTime ltt_time;
-  guint64 time;
+  Tab *tab = event_viewer_data->tab;
   GtkTreeIter iter;
   GtkTreeModel* model = GTK_TREE_MODEL(event_viewer_data->store_m);
   GtkTreePath *path;
-  
+  LttvTracesetContextPosition *pos;
+
+  g_debug("cursor changed cb");
+
   /* On cursor change, modify the currently selected event by calling
    * the right API function */
-  tree_v_get_cursor(event_viewer_data);
-  
-  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, TIME_COLUMN, &time, -1);
-    ltt_time.tv_sec = time / NANOSECONDS_PER_SECOND;
-    ltt_time.tv_nsec = time % NANOSECONDS_PER_SECOND;
-    if(ltt_time.tv_sec != event_viewer_data->current_time.tv_sec ||
-       ltt_time.tv_nsec != event_viewer_data->current_time.tv_nsec){
-      event_viewer_data->current_time_updated = TRUE;
-      set_current_time(event_viewer_data->mw,&ltt_time);
+  if(event_viewer_data->report_position) {
+    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);
+                       }
+               }
+       }
+}
+
+
+static void tree_selection_changed_cb (GtkTreeSelection *selection,
+    gpointer data)
+{
+  g_debug("tree sel changed cb");
+  EventViewerData *event_viewer_data = (EventViewerData*) data;
+#if 0
+    /* Set the cursor to currently selected event */
+  GtkTreeModel* model = GTK_TREE_MODEL(event_viewer_data->store_m);
+  GtkTreeIter iter;
+  LttvTracesetContextPosition *pos;
+  guint i;
+  GtkTreePath *tree_path;
+
+  for(i=0;i<event_viewer_data->num_visible_events;i++) {
+    tree_path = gtk_tree_path_new_from_indices(
+                i,
+               -1);
+    if(gtk_tree_model_get_iter(model,&iter,tree_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) {
+        /* Match! */
+            gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+                tree_path, NULL, FALSE);
+        break;
+      }
+      
+    }else{
+      g_warning("Can not get iter\n");
     }
-  }else{
-    g_warning("Can not get iter\n");
+   gtk_tree_path_free(tree_path);
   }
+#endif //0
+}
 
+#if 0
+static gint key_snooper(GtkWidget *grab_widget, GdkEventKey *event,
+    gpointer func_data)
+{
+  return TRUE;
 }
+#endif //0
 
+/* This callback may be recalled after a step up/down, but we don't want to lose
+ * the exact position : what we do is that we only set the value if it has
+ * changed : a step up/down that doesn't change the time value of the first
+ * event won't trigger a scrollbar change. */
 
 void v_scroll_cb (GtkAdjustment *adjustment, gpointer data)
 {
   EventViewerData *event_viewer_data = (EventViewerData*)data;
-  GtkTreePath *tree_path;
+  LttvTracesetStats *tss =
+    lttvwindow_get_traceset_stats(event_viewer_data->tab);
+  LttvTracesetContext *tsc = (LttvTracesetContext*)tss;
+  g_debug("SCROLL begin");
+  g_debug("SCROLL values : %g , %g, %g",
+      adjustment->value, event_viewer_data->previous_value,
+      (adjustment->value - event_viewer_data->previous_value));
 
-  get_test_data(adjustment->value, event_viewer_data->num_visible_events, 
-    event_viewer_data);
+  LttTime new_time_off = ltt_time_from_double(adjustment->value);
+  LttTime old_time_off = ltt_time_from_double(event_viewer_data->previous_value);
+  g_debug("SCROLL time values %lu.%lu, %lu.%lu", new_time_off.tv_sec,
+      new_time_off.tv_nsec, old_time_off.tv_sec, old_time_off.tv_nsec);
+  /* If same value : nothing to update */
+  if(ltt_time_compare(new_time_off, old_time_off) == 0)
+    return;
   
+  //LttTime old_time = event_viewer_data->first_event;
   
-  if(event_viewer_data->currently_selected_event
-     >= event_viewer_data->first_event
-     &&
-     event_viewer_data->currently_selected_event
-     <= event_viewer_data->last_event
-     &&
-     event_viewer_data->selected_event)
-    {
+
+  //gint snoop = gtk_key_snooper_install(key_snooper, NULL);
+  
+  get_events(adjustment->value, event_viewer_data);
+
+  //gtk_key_snooper_remove(snoop);
+#if 0 
+  LttTime time = ltt_time_sub(event_viewer_data->first_event,
+                              tsc->time_span.start_time);
+  double value = ltt_time_to_double(time);
+  gtk_adjustment_set_value(event_viewer_data->vadjust_c, value);
+  
+  if(event_viewer_data->currently_selected_event != -1) {
       
       tree_path = gtk_tree_path_new_from_indices(
-             event_viewer_data->currently_selected_event-
-             event_viewer_data->first_event,
+             event_viewer_data->currently_selected_event,
              -1);
       
       //      gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), tree_path,
       //             NULL, FALSE);
       gtk_tree_path_free(tree_path);
-    }
-  
+  }
+#endif //0
+  g_debug("SCROLL end");
 }
 
-gint get_cell_height(GtkTreeView *TreeView)
+static __inline gint get_cell_height(GtkTreeView *TreeView)
 {
-  gint height, width;
+  gint height;
   GtkTreeViewColumn *column = gtk_tree_view_get_column(TreeView, 0);
-  GList *Render_List = gtk_tree_view_column_get_cell_renderers(column);
-  GtkCellRenderer *renderer = g_list_first(Render_List)->data;
   
   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;
 }
 
@@ -714,8 +1217,8 @@ void tree_v_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer
   gdouble exact_num_visible;
   
   exact_num_visible = ( alloc->height -
-      TREE_VIEW_HEADER_HEIGHT (GTK_TREE_VIEW(event_viewer_data->tree_v)) )
-    / (double)cell_height ;
+          event_viewer_data->header_height )
+            / (double)cell_height ;
   
   event_viewer_data->num_visible_events = ceil(exact_num_visible) ;
   
@@ -725,12 +1228,14 @@ void tree_v_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer
   event_viewer_data->vadjust_c->page_size =
     floor(exact_num_visible);
 */
-  
+  g_debug("size allocate : last_num_visible_events : %d,\
+           num_visible_events : %d",
+           last_num_visible_events,
+           event_viewer_data->num_visible_events);
   if(event_viewer_data->num_visible_events != last_num_visible_events)
     {
-      get_test_data(event_viewer_data->vadjust_c->value,
-        event_viewer_data->num_visible_events, 
-        event_viewer_data);
+      get_events(event_viewer_data->vadjust_c->value, event_viewer_data);
     }
   
 
@@ -742,19 +1247,19 @@ void tree_v_size_request_cb (GtkWidget *widget, GtkRequisition *requisition, gpo
   EventViewerData *event_viewer_data = (EventViewerData*)data;
   gint cell_height = get_cell_height(GTK_TREE_VIEW(event_viewer_data->tree_v));
   
-  h = cell_height + TREE_VIEW_HEADER_HEIGHT
-    (GTK_TREE_VIEW(event_viewer_data->tree_v));
+  h = cell_height + event_viewer_data->header_height;
   requisition->height = h;
   
 }
 
+#if 0
 gboolean show_event_detail(void * hook_data, void * call_data)
 {
   EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
-  LttvTracesetContext * tsc = get_traceset_context(event_viewer_data->mw);
+  LttvTracesetContext * tsc = lttvwindow_get_traceset_context(event_viewer_data->tab);
 
-  if(event_viewer_data->raw_trace_data_queue_tmp->length == 0 &&
-     event_viewer_data->raw_trace_data_queue->length == 0){
+  if(event_viewer_data->event_fields_queue_tmp->length == 0 &&
+     event_viewer_data->event_fields_queue->length == 0){
     event_viewer_data->shown = FALSE;
     return FALSE;
   }
@@ -762,9 +1267,9 @@ gboolean show_event_detail(void * hook_data, void * call_data)
   if(event_viewer_data->shown == FALSE){
     event_viewer_data->shown = TRUE;
     update_raw_data_array(event_viewer_data, 
-        event_viewer_data->raw_trace_data_queue_tmp->length);
+        event_viewer_data->event_fields_queue_tmp->length);
 
-    get_test_data(event_viewer_data->vadjust_c->value,
+    get_data(event_viewer_data->vadjust_c->value,
       event_viewer_data->num_visible_events, 
       event_viewer_data);
 
@@ -773,1067 +1278,605 @@ gboolean show_event_detail(void * hook_data, void * call_data)
 
   return FALSE;
 }
+#endif //0
 
-void insert_data_into_model(EventViewerData *event_viewer_data, int start, int end)
+static gboolean events_check_handler(guint count, gboolean *stop_flag)
 {
-  int i;
-  guint64 real_data;
-  RawTraceData * raw_data;
-  GList * first;
-  GtkTreeIter iter;
-
-  first = event_viewer_data->raw_trace_data_queue->head;
-  for(i=start; i<end; i++){
-    if(i>=event_viewer_data->number_of_events) break;    
-    raw_data = (RawTraceData*)g_list_nth_data(first, i);
-    
-    // Add a new row to the model 
-    real_data = raw_data->time.tv_sec;
-    real_data *= NANOSECONDS_PER_SECOND;
-    real_data += raw_data->time.tv_nsec;
-    gtk_list_store_append (event_viewer_data->store_m, &iter);
-    gtk_list_store_set (event_viewer_data->store_m, &iter,
-      CPUID_COLUMN, raw_data->cpu_id,
-      EVENT_COLUMN, raw_data->event_name,
-      TIME_COLUMN, real_data,
-      PID_COLUMN, raw_data->pid,
-      ENTRY_LEN_COLUMN, raw_data->entry_length,
-      EVENT_DESCR_COLUMN, raw_data->event_description,
-      -1);
-  }
+  if(count % CHECK_GDK_INTERVAL == 0) {
+    gtk_main_iteration_do(FALSE);
+    if(*stop_flag)
+      return TRUE;
+    else
+      return FALSE;
+  } else return FALSE;
 }
 
-void get_test_data(double time_value, guint list_height, 
-       EventViewerData *event_viewer_data)
+static void get_events(double new_value, EventViewerData *event_viewer_data)
 {
-  GtkTreeIter iter;
-  int i;
-  GtkTreeModel *model = GTK_TREE_MODEL(event_viewer_data->store_m);
   GtkTreePath *tree_path;
-  RawTraceData * raw_data;
-  ScrollDirection  direction = SCROLL_NONE;
-  GList * first;
-  int event_number;
-  double value = event_viewer_data->previous_value - time_value;
-  LttTime start, end, time;
-  LttEvent * ev;
-  unsigned backward_num, minNum, maxNum;
-  LttTracefile * tf;
-  unsigned  block_num, event_num;
-  unsigned size = 1, count = 0;
-  gboolean need_backward_again, backward;
-  GdkWindow * win;
-  GdkCursor * new;
-  GtkWidget* widget = gtk_widget_get_parent(event_viewer_data->hbox_v);
-  
-  if(widget){
-    new = gdk_cursor_new(GDK_X_CURSOR);
-    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);
-  }
-
-
-  //  if(event_number > event_viewer_data->last_event ||
-  //     event_number + list_height-1 < event_viewer_data->first_event ||
-  //     event_viewer_data->first_event == -1)
-  {
-    /* no event can be reused, clear and start from nothing */
-    if(value == -1.0)      direction = SCROLL_STEP_DOWN;
-    else if(value == 1.0 ) direction = SCROLL_STEP_UP;
-    else if(value == -2.0) direction = SCROLL_PAGE_DOWN;
-    else if(value == 2.0 ) direction = SCROLL_PAGE_UP;
-    else if(value == 0.0 ) direction = SCROLL_NONE;
-    else direction = SCROLL_JUMP;
-
-    switch(direction){
-      case SCROLL_STEP_UP:
-      case SCROLL_PAGE_UP:
-  if(direction == SCROLL_PAGE_UP){
-    backward = list_height>event_viewer_data->start_event_index ? TRUE : FALSE;
-  }else{
-    backward = event_viewer_data->start_event_index == 0 ? TRUE : FALSE;
-  }
-  if(backward){
-    event_viewer_data->append = FALSE;
-    do{
-      if(direction == SCROLL_PAGE_UP){
-        minNum = list_height - event_viewer_data->start_event_index ;
-      }else{
-        minNum = 1;
-      }
+  LttvTracesetStats *tss =
+    lttvwindow_get_traceset_stats(event_viewer_data->tab);
+  LttvTracesetContext *tsc = (LttvTracesetContext*)tss;
+  guint i;
+  gboolean seek_by_time;
+  
+  if(lttvwindow_preempt_count > 0) return;
 
-      first = event_viewer_data->raw_trace_data_queue->head;
-      if(!first)break;
-      raw_data = (RawTraceData*)g_list_nth_data(first,0);
-      end = raw_data->time;
-      end.tv_nsec--;
-      ltt_event_position_get(raw_data->ep, &block_num, &event_num, &tf);
-      if(size !=0){
-        if(event_num > minNum){
-    backward_num = event_num > RESERVE_SMALL_SIZE 
-                  ? event_num - RESERVE_SMALL_SIZE : 1;
-    ltt_event_position_set(raw_data->ep, block_num, backward_num);
-    ltt_tracefile_seek_position(tf, raw_data->ep);
-    ev = ltt_tracefile_read(tf);
-    start = ltt_event_time(ev);
-    maxNum = RESERVE_SMALL_SIZE_CUBE;
-        }else{
-    if(block_num > 1){
-      ltt_event_position_set(raw_data->ep, block_num-1, 1);
-      ltt_tracefile_seek_position(tf, raw_data->ep);
-      ev = ltt_tracefile_read(tf);
-      start = ltt_event_time(ev);             
-    }else{
-      start.tv_sec  = 0;
-      start.tv_nsec = 0;    
-    }
-    maxNum = RESERVE_SMALL_SIZE_CUBE;
-        }
-      }else{
-        if(block_num > count){
-    ltt_event_position_set(raw_data->ep, block_num-count, 1);
-    ltt_tracefile_seek_position(tf, raw_data->ep);
-    ev = ltt_tracefile_read(tf);
-    start = ltt_event_time(ev);             
-        }else{
-    start.tv_sec  = 0;
-    start.tv_nsec = 0;    
-        }       
-        maxNum = RESERVE_SMALL_SIZE_CUBE;
-      }
+  double value = new_value - event_viewer_data->previous_value;
 
-      event_viewer_data->current_event_index = event_viewer_data->start_event_index;
-      get_events(event_viewer_data, start, end, maxNum, &size);
-      event_viewer_data->start_event_index = event_viewer_data->current_event_index;
-
-      if(size < minNum && (start.tv_sec !=0 || start.tv_nsec !=0))
-        need_backward_again = TRUE;
-      else need_backward_again = FALSE;
-      if(size == 0){
-        count++;
-      }else{
-        count = 0;
-      }
-    }while(need_backward_again);
-  }
-  if(direction == SCROLL_STEP_UP)
-    event_number = event_viewer_data->start_event_index - 1;       
-  else
-    event_number = event_viewer_data->start_event_index - list_height;          
-  break;
-      case SCROLL_STEP_DOWN:
-  if(event_viewer_data->end_event_index == event_viewer_data->number_of_events - 1){
-    event_viewer_data->append = TRUE;
-    first = event_viewer_data->raw_trace_data_queue->head;
-    if(!first)break;
-    raw_data = (RawTraceData*)g_list_nth_data(first,event_viewer_data->number_of_events - 1);
-    start = raw_data->time;
-    start.tv_nsec++;
-    end.tv_sec = G_MAXULONG;
-    end.tv_nsec = G_MAXULONG;
-    get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE, &size);
-    if(size == 0){
-      get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_SQUARE,&size);
-      if(size == 0)
-        get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_CUBE,&size);
-    }
-    if(size==0) event_number = event_viewer_data->start_event_index;  
-    else event_number = event_viewer_data->number_of_events - size - list_height + 1;
-  }else event_number = event_viewer_data->start_event_index + 1;
-  break;
-      case SCROLL_PAGE_DOWN:
-  i = event_viewer_data->number_of_events - 1 - list_height;
-  if((gint)(event_viewer_data->end_event_index) >= i){
-    int remain_events = event_viewer_data->number_of_events - 1 
-                        -  event_viewer_data->end_event_index;
-    event_viewer_data->append = TRUE;
-    first = event_viewer_data->raw_trace_data_queue->head;
-    if(!first)break;
-    raw_data = (RawTraceData*)g_list_nth_data(first,event_viewer_data->number_of_events - 1);
-    start = raw_data->time;
-    start.tv_nsec++;
-    end.tv_sec = G_MAXULONG;
-    end.tv_nsec = G_MAXULONG;
-    get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE,&size);
-    if(size == 0){
-      get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_SQUARE,&size);
-      if(size == 0)
-        get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_CUBE,&size);
+  /* 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(value < -0.8) {
+    if(value >= -1.0) direction = SCROLL_STEP_UP;
+    else {
+      if(value >= -2.0) direction = SCROLL_PAGE_UP;
+      else direction = SCROLL_JUMP;
     }
-    remain_events += size;
-    if(list_height <= remain_events)
-      event_number = event_viewer_data->number_of_events - remain_events - 1; 
-    else
-      event_number = event_viewer_data->number_of_events - 1 - list_height;     
-  }else event_number = event_viewer_data->start_event_index + list_height - 1;
-  break;
-      case SCROLL_JUMP:
-  event_viewer_data->append = TRUE;
-  remove_all_items_from_queue(event_viewer_data->raw_trace_data_queue);
-  end.tv_sec = G_MAXULONG;
-  end.tv_nsec = G_MAXULONG;
-  time = ltt_time_from_double(time_value / NANOSECONDS_PER_SECOND);
-  start = ltt_time_add(event_viewer_data->time_span.startTime, time);
-  event_viewer_data->previous_value = time_value;
-  get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE,&size);
-  if(size < list_height && size > 0){
-    event_viewer_data->append = FALSE;
-    first = event_viewer_data->raw_trace_data_queue->head;
-    if(!first)break;
-    raw_data = (RawTraceData*)g_list_nth_data(first,0);
-    end = raw_data->time;
-    end.tv_nsec--;
-    ltt_event_position_get(raw_data->ep, &block_num, &event_num, &tf);
-    
-    if(event_num > list_height - size){
-      backward_num = event_num > RESERVE_SMALL_SIZE 
-        ? event_num - RESERVE_SMALL_SIZE : 1;
-      ltt_event_position_set(raw_data->ep, block_num, backward_num);
-      ltt_tracefile_seek_position(tf, raw_data->ep);
-      ev = ltt_tracefile_read(tf);
-      start = ltt_event_time(ev);
-      maxNum = RESERVE_SMALL_SIZE_CUBE;
-      event_viewer_data->current_event_index = 0;
-      get_events(event_viewer_data, start, end, maxNum, &size);
-      event_viewer_data->start_event_index = event_viewer_data->current_event_index;
+  } else if(value > 0.8) {
+    if(value <= 1.0) direction = SCROLL_STEP_DOWN;
+    else {
+      if(value <= 2.0) direction = SCROLL_PAGE_DOWN;
+      else direction = SCROLL_JUMP;
     }
-    event_number = event_viewer_data->raw_trace_data_queue->length - list_height;
-  }else if(size == 0){
-    get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_SQUARE,&size);
-    if(size == 0)
-      get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_CUBE,&size);
-    event_number = 0;
-  }else{
-    event_number = 0;
-  }
-  break;
-      case SCROLL_NONE:
-  event_number = event_viewer_data->current_event_index;
-  break;
-      default:
+  } else direction = SCROLL_NONE; /* 0.0 */
+
+
+  switch(direction) {
+  case SCROLL_STEP_UP:
+    g_debug("get_events : SCROLL_STEP_UP");
+    relative_position = -1;
+    seek_by_time = 0;
     break;
-    }
+  case SCROLL_STEP_DOWN:
+    g_debug("get_events : SCROLL_STEP_DOWN");
+    relative_position = 1;
+    seek_by_time = 0;
+    break;
+  case SCROLL_PAGE_UP:
+    g_debug("get_events : SCROLL_PAGE_UP");
+    relative_position = -(event_viewer_data->num_visible_events);
+    seek_by_time = 0;
+    break;
+  case SCROLL_PAGE_DOWN:
+    g_debug("get_events : SCROLL_PAGE_DOWN");
+    relative_position = event_viewer_data->num_visible_events;
+    seek_by_time = 0;
+    break;
+  case SCROLL_JUMP:
+    g_debug("get_events : SCROLL_JUMP");
+    seek_by_time = 1;
+    break;
+  case SCROLL_NONE:
+    g_debug("get_events : SCROLL_NONE");
+    relative_position = 0;
+    seek_by_time = 0;
+    break;
+  }
+
+  LttTime time = ltt_time_from_double(new_value);
+  time = ltt_time_add(tsc->time_span.start_time, time);
 
-    if(event_number < 0) event_number = 0;
-
-    //update the value of the scroll bar
-    if(direction != SCROLL_NONE && direction != SCROLL_JUMP){
-      first = event_viewer_data->raw_trace_data_queue->head;
-      if(first){
-  raw_data = (RawTraceData*)g_list_nth_data(first,event_number);
-  if(!raw_data) raw_data = (RawTraceData*)g_list_nth_data(first,0);       
-  time = ltt_time_sub(raw_data->time, event_viewer_data->time_span.startTime);
-  event_viewer_data->vadjust_c->value = ltt_time_to_double(time) * NANOSECONDS_PER_SECOND;
-  g_signal_stop_emission_by_name(G_OBJECT(event_viewer_data->vadjust_c), "value-changed");
-  event_viewer_data->previous_value = event_viewer_data->vadjust_c->value;
+  if(!seek_by_time) {
+  
+    LttvTracesetContextPosition *pos =
+        lttv_traceset_context_position_new(tsc);
+    
+    /* Remember the beginning position */
+    if(event_viewer_data->pos->len > 0) {
+      LttvTracesetContextPosition *first_pos = 
+        (LttvTracesetContextPosition*)g_ptr_array_index(
+                                                    event_viewer_data->pos,
+                                                    0);
+      lttv_traceset_context_position_copy(pos, first_pos);
+
+      if(relative_position >= 0) {
+        LttTime first_event_time = 
+            lttv_traceset_context_position_get_time(
+                              pos);
+        lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc,
+          first_event_time);
+        lttv_process_traceset_middle(tsc, ltt_time_infinite,
+                                   G_MAXUINT,
+                                   pos);
+       
+      } else if(relative_position < 0) {
+        g_assert(lttv_process_traceset_seek_position(tsc, pos) == 0); 
       }
+    } else {
+      /* There is nothing in the list : simply seek to the time value. */
+      lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc,
+          time);
+      lttv_process_traceset_middle(tsc, time, G_MAXUINT,
+                                   NULL);
     }
     
-
-    event_viewer_data->start_event_index = event_number;
-    event_viewer_data->end_event_index = event_number + list_height - 1;    
-    if(event_viewer_data->end_event_index > event_viewer_data->number_of_events - 1){
-      event_viewer_data->end_event_index = event_viewer_data->number_of_events - 1;
-    }
-
-    first = event_viewer_data->raw_trace_data_queue->head;
-    gtk_list_store_clear(event_viewer_data->store_m);
-    if(!first){
-      //      event_viewer_data->previous_value = 0;
-      //      event_viewer_data->vadjust_c->value = 0.0;
-      //      gtk_widget_hide(event_viewer_data->vscroll_vc);
-      goto LAST;
-    }else gtk_widget_show(event_viewer_data->vscroll_vc);
-
-    insert_data_into_model(event_viewer_data,event_number, event_number+list_height);
-  }
-#ifdef DEBUG //do not use this, it's slower and broken
-  //  } else {
-  /* Some events will be reused */
-  if(event_number < event_viewer_data->first_event)
-    {
-      /* scrolling up, prepend events */
-      tree_path = gtk_tree_path_new_from_indices
-  (event_number+list_height-1 -
-   event_viewer_data->first_event + 1,
-   -1);
-      for(i=0; i<event_viewer_data->last_event-(event_number+list_height-1);
-    i++)
-  {
-    /* Remove the last events from the list */
-    if(gtk_tree_model_get_iter(model, &iter, tree_path))
-      gtk_list_store_remove(event_viewer_data->store_m, &iter);
-  }
+  /* Note that, as we mess with the tsc position, this function CANNOT be called
+   * from a hook inside the lttv_process_traceset_middle. */
+  /* As the lttvwindow API keeps a sync_position inside the tsc to go back at
+   * the right spot after being interrupted, it's ok to change the tsc position,
+   * as long as we do not touch the sync_position. */
+
+  /* Get the beginning position of the read (with seek backward or seek forward)
+   */
+    if(relative_position > 0) {
+      guint count;
+      count += lttv_process_traceset_seek_n_forward(tsc, relative_position,
+          events_check_handler,
+          &event_viewer_data->tab->stop_foreground,
+          event_viewer_data->main_win_filter,
+          event_viewer_data->filter, NULL);
+    } else if(relative_position < 0) {
+      guint count;
       
-      for(i=event_viewer_data->first_event-1; i>=event_number; i--)
-  {
-    if(i>=event_viewer_data->number_of_events) break;
-    /* Prepend new events */
-    gtk_list_store_prepend (event_viewer_data->store_m, &iter);
-    gtk_list_store_set (event_viewer_data->store_m, &iter,
-            CPUID_COLUMN, 0,
-            EVENT_COLUMN, "event irq",
-            TIME_COLUMN, i,
-            PID_COLUMN, 100,
-            ENTRY_LEN_COLUMN, 17,
-            EVENT_DESCR_COLUMN, "Detailed information",
-            -1);
-  }
-    } else {
-      /* Scrolling down, append events */
-      for(i=event_viewer_data->first_event; i<event_number; i++)
-  {
-    /* Remove these events from the list */
-    gtk_tree_model_get_iter_first(model, &iter);
-    gtk_list_store_remove(event_viewer_data->store_m, &iter);
+      /* Get an idea of currently shown event dispersion */
+      LttTime first_event_time =
+        lttv_traceset_context_position_get_time(event_viewer_data->first_event);
+      LttTime last_event_time =
+        lttv_traceset_context_position_get_time(event_viewer_data->last_event);
+      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),
+          time_diff,
+          (seek_time_fct)lttv_state_traceset_seek_time_closest,
+         events_check_handler,
+         &event_viewer_data->tab->stop_foreground,
+          event_viewer_data->main_win_filter,
+          event_viewer_data->filter, NULL);
+    } /* else 0 : do nothing : we are already at the beginning position */
+
+    lttv_traceset_context_position_destroy(pos);
+
+    /* Save the first event position */
+    lttv_traceset_context_position_save(tsc, event_viewer_data->first_event);
+    
+    time = lttv_traceset_context_position_get_time(
+                                            event_viewer_data->first_event);
+    //if(ltt_time_compare(time, tsc->time_span.end_time) > 0)
+    //  time = tsc->time_span.end_time;
+
+    LttTime time_val = ltt_time_sub(time,
+                        tsc->time_span.start_time);
+    event_viewer_data->previous_value = ltt_time_to_double(time_val);
+    
+    lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc, time);
+    lttv_process_traceset_middle(tsc, ltt_time_infinite, G_MAXUINT,
+                                 event_viewer_data->first_event);
+
+  } else {
+    /* Seek by time */
+    lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc,
+          time);
+    lttv_process_traceset_middle(tsc, time, G_MAXUINT,
+                                 NULL);
+    LttTime time_val = ltt_time_sub(time,
+                        tsc->time_span.start_time);
+    event_viewer_data->previous_value = ltt_time_to_double(time_val);
+    lttv_traceset_context_position_save(tsc, event_viewer_data->first_event);
   }
-      for(i=event_viewer_data->last_event+1; i<event_number+list_height; i++)
-  {
-    if(i>=event_viewer_data->number_of_events) break;
-    /* Append new events */
-    gtk_list_store_append (event_viewer_data->store_m, &iter);
-    gtk_list_store_set (event_viewer_data->store_m, &iter,
-            CPUID_COLUMN, 0,
-            EVENT_COLUMN, "event irq",
-            TIME_COLUMN, i,
-            PID_COLUMN, 100,
-            ENTRY_LEN_COLUMN, 17,
-            EVENT_DESCR_COLUMN, "Detailed information",
-            -1);
+  /* Clear the model (don't forget to free the TCS positions!) */
+  gtk_list_store_clear(event_viewer_data->store_m);
+  for(i=0;i<event_viewer_data->pos->len;i++) {
+    LttvTracesetContextPosition *cur_pos = 
+      (LttvTracesetContextPosition*)g_ptr_array_index(event_viewer_data->pos,
+                                                      i);
+    lttv_traceset_context_position_destroy(cur_pos);
   }
-      
-    }
-  //}
-#endif //DEBUG
-  event_viewer_data->first_event = event_viewer_data->start_event_index ;
-  event_viewer_data->last_event = event_viewer_data->end_event_index ;
-
- LAST:
-  if(widget)
-     gdk_window_set_cursor(win, NULL);  
+  g_ptr_array_set_size(event_viewer_data->pos, 0);
+  
 
-}
+  /* 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. 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);
 
-void add_test_data(EventViewerData *event_viewer_data)
-{
-  GtkTreeIter iter;
-  int i;
+  event_viewer_data->num_events = 0;
   
-  for(i=0; i<10; i++)
-    {
-      /* Add a new row to the model */
-      gtk_list_store_append (event_viewer_data->store_m, &iter);
-      gtk_list_store_set (event_viewer_data->store_m, &iter,
-        CPUID_COLUMN, 0,
-        EVENT_COLUMN, "event irq",
-        TIME_COLUMN, i,
-        PID_COLUMN, 100,
-        ENTRY_LEN_COLUMN, 17,
-        EVENT_DESCR_COLUMN, "Detailed information",
-        -1);
-    }
+  lttv_process_traceset_middle(tsc, ltt_time_infinite, G_MAXUINT, NULL);
   
-}
+  lttv_process_traceset_end(tsc,
+      NULL, NULL, NULL, event_viewer_data->event_hooks, NULL);
   
-void
-gui_events_free(EventViewerData *event_viewer_data)
-{
-  if(event_viewer_data){
-    lttv_hooks_remove(event_viewer_data->before_event_hooks,parse_event);
-    lttv_hooks_destroy(event_viewer_data->before_event_hooks);
-    
-    remove_all_items_from_queue (event_viewer_data->raw_trace_data_queue);
-    g_queue_free(event_viewer_data->raw_trace_data_queue);
-    g_queue_free(event_viewer_data->raw_trace_data_queue_tmp);
-
-    unreg_update_time_window(update_time_window,event_viewer_data, event_viewer_data->mw);
-    unreg_update_current_time(update_current_time,event_viewer_data, event_viewer_data->mw);
-    unreg_show_viewer(show_event_detail,event_viewer_data, event_viewer_data->mw);
-    unreg_update_traceset(traceset_changed,event_viewer_data, event_viewer_data->mw);
-
-    g_free(event_viewer_data->filter_key);
-    g_event_viewer_data_list = g_slist_remove(g_event_viewer_data_list, event_viewer_data);
-    g_free(event_viewer_data);
-  }
-}
+  /* Get the end position */
+  if(event_viewer_data->pos->len > 0) {
+    LttvTracesetContextPosition *cur_pos = 
+      (LttvTracesetContextPosition*)g_ptr_array_index(event_viewer_data->pos,
+                                               event_viewer_data->pos->len - 1);
+    lttv_traceset_context_position_copy(event_viewer_data->last_event,
+        cur_pos);
+  } else
+    lttv_traceset_context_position_save(tsc, event_viewer_data->last_event);
 
-void
-gui_events_destructor(EventViewerData *event_viewer_data)
-{
-  guint index;
-
-  /* May already been done by GTK window closing */
-  if(GTK_IS_WIDGET(event_viewer_data->hbox_v)){
-    gui_events_free(event_viewer_data);
-    gtk_widget_destroy(event_viewer_data->hbox_v);
-    event_viewer_data = NULL;
-  }
+  gtk_adjustment_set_value(event_viewer_data->vadjust_c,
+      event_viewer_data->previous_value);
   
-  /* Destroy the Tree View */
-  //gtk_widget_destroy(event_viewer_data->tree_v);
+  //g_signal_emit_by_name(G_OBJECT (event_viewer_data->select_c),
+  //    "changed");
   
-  /*  Clear raw event list */
-  //gtk_list_store_clear(event_viewer_data->store_m);
-  //gtk_widget_destroy(GTK_WIDGET(event_viewer_data->store_m));
-  
-  //gui_events_free(event_viewer_data);
+  event_viewer_data->last_tree_update_time = 
+    gdk_x11_get_server_time(
+        gtk_widget_get_parent_window(event_viewer_data->tree_v));
+
+  lttvwindow_events_request_enable();
+
+  return;
 }
 
-//FIXME : call hGuiEvents_Destructor for corresponding data upon widget destroy
 
-static void
-tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data)
+int event_hook(void *hook_data, void *call_data)
 {
-  EventViewerData *event_viewer_data = (EventViewerData*)data;
-  GtkTreeIter iter;
-  GtkTreeModel *model = GTK_TREE_MODEL(event_viewer_data->store_m);
-  gchar *event;
+  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++;
   
-  if (gtk_tree_selection_get_selected (selection, &model, &iter))
-    {
-      gtk_tree_model_get (model, &iter, EVENT_COLUMN, &event, -1);
-      
-      g_free (event);
-    }
-}
+  LttvFilter *filter = event_viewer_data->main_win_filter;
+  if(filter != NULL && filter->head != NULL)
+    if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
+          tfc->t_context->t,tfc))
+      return FALSE;
 
+  filter = event_viewer_data->filter;
+  if(filter != NULL && filter->head != NULL)
+    if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
+          tfc->t_context->t,tfc))
+      return FALSE;
 
-int event_selected_hook(void *hook_data, void *call_data)
-{
-  EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
-  guint *event_number = (guint*) call_data;
+
+  LttFacility *facility = ltt_event_facility(e);
+  LttEventType *event_type = ltt_event_eventtype(e);
+  LttTime time = ltt_event_time(e);
+
+  guint cpu = tfs->cpu;
+  LttvTraceState *ts = (LttvTraceState*)tfc->t_context;
+  LttvProcessState *process = ts->running_process[cpu];
   
-  event_viewer_data->currently_selected_event = *event_number;
-  event_viewer_data->selected_event = TRUE ;
+  GtkTreeIter iter;
+
+  GString *desc = g_string_new("");
   
-  tree_v_set_cursor(event_viewer_data);
+  LttvTracesetContextPosition *pos =
+    lttv_traceset_context_position_new(tfc->t_context->ts_context);
 
-}
+  lttv_traceset_context_position_save(tfc->t_context->ts_context, pos);
 
-/* If every module uses the filter, maybe these two 
- * (add/remove_context_hooks functions) should be put in common place
- */
-void add_context_hooks(EventViewerData * event_viewer_data, 
-           LttvTracesetContext * tsc)
-{
-  gint i, j, k, m,n, nbi, id;
-  gint nb_tracefile, nb_facility, nb_event;
-  LttTrace *trace;
-  LttvTraceContext *tc;
-  LttvTracefileContext *tfc;
-  LttvTracesetSelector  * ts_s;
-  LttvTraceSelector     * t_s;
-  LttvTracefileSelector * tf_s;
-  gboolean selected;
-  LttFacility           * fac;
-  LttEventType          * et;
-  LttvEventtypeSelector * eventtype;
-
-  ts_s = (LttvTracesetSelector*)g_object_get_data(G_OBJECT(event_viewer_data->hbox_v), 
-              event_viewer_data->filter_key);
-
-  //if there are hooks for traceset, add them here
-  
-  nbi = lttv_traceset_number(tsc->ts);
-  for(i = 0 ; i < nbi ; i++) {
-    t_s = lttv_traceset_selector_trace_get(ts_s,i);
-    selected = lttv_trace_selector_get_selected(t_s);
-    if(!selected) continue;
-    tc = tsc->traces[i];
-    trace = tc->t;
-    //if there are hooks for trace, add them here
-
-    nb_tracefile = ltt_trace_control_tracefile_number(trace) +
-        ltt_trace_per_cpu_tracefile_number(trace);
-    
-    for(j = 0 ; j < nb_tracefile ; j++) {
-      tf_s = lttv_trace_selector_tracefile_get(t_s,j);
-      selected = lttv_tracefile_selector_get_selected(tf_s);
-      if(!selected) continue;
-      tfc = tc->tracefiles[j];
-      
-      //if there are hooks for tracefile, add them here
-      //      lttv_tracefile_context_add_hooks(tfc, NULL,NULL,NULL,NULL,
-      //               event_viewer_data->before_event_hooks,NULL);
-
-      nb_facility = ltt_trace_facility_number(trace);
-      n = 0;
-      for(k=0;k<nb_facility;k++){
-  fac = ltt_trace_facility_get(trace,k);
-  nb_event = (int) ltt_facility_eventtype_number(fac);
-  for(m=0;m<nb_event;m++){
-    et = ltt_facility_eventtype_get(fac,m);
-    eventtype = lttv_tracefile_selector_eventtype_get(tf_s, n);
-    selected = lttv_eventtype_selector_get_selected(eventtype);
-    if(selected){
-      id = (gint) ltt_eventtype_id(et);
-      lttv_tracefile_context_add_hooks_by_id(tfc,id, 
-               event_viewer_data->before_event_hooks,
-               NULL);
-    }
-    n++;
-  }
-      }
+  lttv_event_to_string(e, desc, TRUE, TRUE, (LttvTracefileState*)tfc);
 
+  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,
+      TRACE_NAME_COLUMN, g_quark_to_string(ltt_trace_name(tfc->t_context->t)),
+      TRACEFILE_NAME_COLUMN, g_quark_to_string(ltt_tracefile_name(tfc->tf)),
+      CPUID_COLUMN, cpu,
+      FACILITY_COLUMN, g_quark_to_string(ltt_facility_name(facility)),
+      EVENT_COLUMN, g_quark_to_string(ltt_eventtype_name(event_type)),
+      TIME_S_COLUMN, time.tv_sec,
+      TIME_NS_COLUMN, time.tv_nsec,
+      PID_COLUMN, process->pid,
+      EVENT_DESCR_COLUMN, desc->str,
+      POSITION_COLUMN, pos,
+      -1);
+
+  g_ptr_array_add(event_viewer_data->pos, pos);
+  
+  g_string_free(desc, TRUE);
+
+  if(event_viewer_data->update_cursor) {
+    if(lttv_traceset_context_pos_pos_compare(pos, 
+          event_viewer_data->currently_selected_position) == 0) {
+      GtkTreePath *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);
+                       }
     }
   }
   
-  //add hooks for process_traceset
-  //    context_add_hooks_api(event_viewer_data->mw, NULL, NULL, NULL, NULL, NULL, NULL,
-  //        NULL, NULL, NULL,event_viewer_data->before_event_hooks,NULL);  
+  if(event_viewer_data->pos->len >= event_viewer_data->num_visible_events )
+    return TRUE;
+  else
+    return FALSE;
 }
 
 
-void remove_context_hooks(EventViewerData * event_viewer_data, 
-        LttvTracesetContext * tsc)
+
+static void event_update_selection(EventViewerData *event_viewer_data)
 {
-  gint i, j, k, m, nbi, n, id;
-  gint nb_tracefile, nb_facility, nb_event;
-  LttTrace *trace;
-  LttvTraceContext *tc;
-  LttvTracefileContext *tfc;
-  LttvTracesetSelector  * ts_s;
-  LttvTraceSelector     * t_s;
-  LttvTracefileSelector * tf_s;
-  gboolean selected;
-  LttFacility           * fac;
-  LttEventType          * et;
-  LttvEventtypeSelector * eventtype;
-
-  ts_s = (LttvTracesetSelector*)g_object_get_data(G_OBJECT(event_viewer_data->hbox_v), 
-              event_viewer_data->filter_key);
-
-  //if there are hooks for traceset, remove them here
-  
-  nbi = lttv_traceset_number(tsc->ts);
-  for(i = 0 ; i < nbi ; i++) {
-    t_s = lttv_traceset_selector_trace_get(ts_s,i);
-    selected = lttv_trace_selector_get_selected(t_s);
-    if(!selected) continue;
-    tc = tsc->traces[i];
-    trace = tc->t;
-    //if there are hooks for trace, remove them here
-
-    nb_tracefile = ltt_trace_control_tracefile_number(trace) +
-        ltt_trace_per_cpu_tracefile_number(trace);
-    
-    for(j = 0 ; j < nb_tracefile ; j++) {
-      tf_s = lttv_trace_selector_tracefile_get(t_s,j);
-      selected = lttv_tracefile_selector_get_selected(tf_s);
-      if(!selected) continue;
-      tfc = tc->tracefiles[j];
-      
-      //if there are hooks for tracefile, remove them here
-      //      lttv_tracefile_context_remove_hooks(tfc, NULL,NULL,NULL,NULL,
-      //            event_viewer_data->before_event_hooks,NULL);
-
-      nb_facility = ltt_trace_facility_number(trace);
-      n = 0;
-      for(k=0;k<nb_facility;k++){
-  fac = ltt_trace_facility_get(trace,k);
-  nb_event = (int) ltt_facility_eventtype_number(fac);
-  for(m=0;m<nb_event;m++){
-    et = ltt_facility_eventtype_get(fac,m);
-    eventtype = lttv_tracefile_selector_eventtype_get(tf_s, n);
-    selected = lttv_eventtype_selector_get_selected(eventtype);
-    if(selected){
-      id = (gint) ltt_eventtype_id(et);
-      lttv_tracefile_context_remove_hooks_by_id(tfc,id); 
-    }
-    n++;
-  }
-      }
+  guint i;
+  GPtrArray *positions = event_viewer_data->pos;
+  g_info("event_update_selection");
+
+  for(i=0;i<positions->len;i++) {
+    LttvTracesetContextPosition *cur_pos = 
+      (LttvTracesetContextPosition*)g_ptr_array_index(positions, i);
+    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);
+                       if(path) {
+             gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+                                    path, NULL, FALSE);
+             gtk_tree_path_free(path);
+                       }
     }
   }
-  //remove hooks from context
-  //    context_remove_hooks_api(event_viewer_data->mw, NULL, NULL, NULL, NULL, NULL, NULL,
-  //           NULL, NULL, NULL,event_viewer_data->before_event_hooks,NULL);
+}
+
+static int current_time_get_first_event_hook(void *hook_data, void *call_data)
+{
+  EventViewerData *event_viewer_data = (EventViewerData*)hook_data;
+  LttvTracefileContext *tfc = (LttvTracefileContext*)call_data;
+  LttEvent *e = ltt_tracefile_get_event(tfc->tf);
+
+  LttvFilter *filter = event_viewer_data->main_win_filter;
+  if(filter != NULL && filter->head != NULL)
+    if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
+          tfc->t_context->t,tfc))
+      return FALSE;
+
+  filter = event_viewer_data->filter;
+  if(filter != NULL && filter->head != NULL)
+    if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
+          tfc->t_context->t,tfc))
+      return FALSE;
+
+  lttv_traceset_context_position_save(tfc->t_context->ts_context, 
+      event_viewer_data->current_time_get_first);
+  return TRUE;
 }
 
 
-gboolean update_time_window(void * hook_data, void * call_data)
+gboolean update_current_time(void * hook_data, void * call_data)
 {
+  g_info("update_current_time");
   EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
-  LttvTracesetContext * tsc = get_traceset_context(event_viewer_data->mw);
-
-  if(event_viewer_data->shown == FALSE){
-    event_viewer_data->time_window = *(TimeWindow*)call_data;
+  const LttTime * current_time = (LttTime*)call_data;
+  LttvTracesetContext * tsc =
+        lttvwindow_get_traceset_context(event_viewer_data->tab);
+  GtkTreePath *path;
+  
+  /* If the currently selected event time != current time, set the first event
+   * with this time as currently selected. */
+  LttTime pos_time = lttv_traceset_context_position_get_time(
+      event_viewer_data->currently_selected_position);
+  if(ltt_time_compare(pos_time, *current_time) != 0) {
+    
+    lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc,
+        *current_time);
+    lttv_process_traceset_middle(tsc, *current_time, G_MAXUINT,
+                                   NULL);
+
+    /* Get the first event that passes in the filter */
+    event_viewer_data->current_time_get_first =
+                lttv_traceset_context_position_new(tsc);
+    LttvHooks *hooks = lttv_hooks_new();
+    lttv_hooks_add(hooks,
+                   current_time_get_first_event_hook,
+                   event_viewer_data,
+                   LTTV_PRIO_DEFAULT);
+
+    lttv_process_traceset_begin(tsc,
+        NULL, NULL, NULL, hooks, NULL);
     
-    add_context_hooks(event_viewer_data, tsc);
+    lttv_process_traceset_middle(tsc, ltt_time_infinite, G_MAXUINT, NULL);
+    
+    lttv_process_traceset_end(tsc,
+        NULL, NULL, NULL, hooks, NULL);
+   
+    lttv_hooks_destroy(hooks);
+
+    lttv_traceset_context_position_copy(
+        event_viewer_data->currently_selected_position,
+        event_viewer_data->current_time_get_first);
+    lttv_traceset_context_position_destroy(
+        event_viewer_data->current_time_get_first);
+    pos_time = lttv_traceset_context_position_get_time(
+        event_viewer_data->currently_selected_position);
   }
 
+  LttTime time = ltt_time_sub(pos_time, tsc->time_span.start_time);
+  double new_value = ltt_time_to_double(time);
+  event_viewer_data->report_position = FALSE;
+  /* Change the viewed area if does not match */
+  if(lttv_traceset_context_pos_pos_compare(
+        event_viewer_data->currently_selected_position,
+        event_viewer_data->first_event) < 0
+    ||
+     lttv_traceset_context_pos_pos_compare(
+        event_viewer_data->currently_selected_position,
+        event_viewer_data->last_event) > 0) {
+    gtk_adjustment_set_value(event_viewer_data->vadjust_c, new_value);
+  } else {
+    /* Simply update the current time : it is in the list */
+    event_update_selection(event_viewer_data);
+  }
+  event_viewer_data->report_position = TRUE;
+  
   return FALSE;
 }
 
-gboolean update_current_time(void * hook_data, void * call_data)
+gboolean update_current_position(void * hook_data, void * call_data)
 {
+  g_info("update_current_position");
   EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
-  event_viewer_data->current_time = *(LttTime*)call_data;
-  guint64 nsec = event_viewer_data->current_time.tv_sec * NANOSECONDS_PER_SECOND 
-                  + event_viewer_data->current_time.tv_nsec;
-  GtkTreeIter iter;
-  guint64 time;
-  int count = -1;
-  GtkTreeModel* model = (GtkTreeModel*)event_viewer_data->store_m;
-  GList * list;
-  RawTraceData * data, *data1;
-  GtkTreePath* path;
-  char str_path[64];
-  int i, j;
-  LttTime t;
-
-  if(!event_viewer_data->raw_trace_data_queue->head) return FALSE;
-
-  if(event_viewer_data->current_time_updated ){
-    event_viewer_data->current_time_updated = FALSE;
-    return FALSE;
-  }
-
-  //check if the event is shown in the current viewer
-  if(gtk_tree_model_get_iter_first(model, &iter)){
-    while(1){
-      gtk_tree_model_get(model, &iter, TIME_COLUMN, &time, -1);
-      if(time < nsec){
-  if(!gtk_tree_model_iter_next(model, &iter)){
-    count = -1;
-    break;
-  }
-  count++;
-      }else{
-  break;
-      }
+  const LttvTracesetContextPosition *current_pos =
+    (LttvTracesetContextPosition*)call_data;
+  LttvTracesetContext * tsc =
+        lttvwindow_get_traceset_context(event_viewer_data->tab);
+  
+  if(lttv_traceset_context_pos_pos_compare(
+        event_viewer_data->currently_selected_position, current_pos) != 0) {
+    lttv_traceset_context_position_copy(
+        event_viewer_data->currently_selected_position, current_pos);
+
+    /* Change the viewed area if does not match */
+    if(lttv_traceset_context_pos_pos_compare(
+          event_viewer_data->currently_selected_position,
+          event_viewer_data->first_event) < 0
+      ||
+       lttv_traceset_context_pos_pos_compare(
+          event_viewer_data->currently_selected_position,
+          event_viewer_data->last_event) > 0) {
+      LttTime time = lttv_traceset_context_position_get_time(current_pos);
+      time = ltt_time_sub(time, tsc->time_span.start_time);
+      double new_value = ltt_time_to_double(time);
+      gtk_adjustment_set_value(event_viewer_data->vadjust_c, new_value);
+    } else {
+      /* Simply update the current time : it is in the list */
+      event_update_selection(event_viewer_data);
     }
-    //    event_selected_hook(event_viewer_data, &count);
-  }
 
-  //the event is not shown in the current viewer
-  if(count == -1){
-    count = 0;
-    //check if the event is in the buffer
-    list = event_viewer_data->raw_trace_data_queue->head;
-    data = (RawTraceData*)g_list_nth_data(list,0);
-    data1 = (RawTraceData*)g_list_nth_data(list,event_viewer_data->raw_trace_data_queue->length-1);
-
-    //the event is in the buffer
-    if(ltt_time_compare(data->time, event_viewer_data->current_time)<=0 &&
-       ltt_time_compare(data1->time, event_viewer_data->current_time)>=0){
-      for(i=0;i<event_viewer_data->raw_trace_data_queue->length;i++){
-  data = (RawTraceData*)g_list_nth_data(list,i);
-  if(ltt_time_compare(data->time, event_viewer_data->current_time) < 0){
-    count++;
-    continue;
-  }
-  break;
-      }
-      if(event_viewer_data->raw_trace_data_queue->length-count < event_viewer_data->num_visible_events){
-  j = event_viewer_data->raw_trace_data_queue->length - event_viewer_data->num_visible_events;
-  count -= j;
-  data = (RawTraceData*)g_list_nth_data(list,j);
-      }else{
-  j = count;
-  count = 0;
-      }
-      t = ltt_time_sub(data->time, event_viewer_data->time_span.startTime);
-      event_viewer_data->vadjust_c->value = ltt_time_to_double(t) * NANOSECONDS_PER_SECOND;
-      g_signal_stop_emission_by_name(G_OBJECT(event_viewer_data->vadjust_c), "value-changed");
-      event_viewer_data->previous_value = event_viewer_data->vadjust_c->value;
-      insert_data_into_model(event_viewer_data,j, j+event_viewer_data->num_visible_events);      
-    }else{//the event is not in the buffer
-      LttTime start = ltt_time_sub(event_viewer_data->current_time, event_viewer_data->time_span.startTime);
-      double position = ltt_time_to_double(start) * NANOSECONDS_PER_SECOND;
-      gtk_adjustment_set_value(event_viewer_data->vadjust_c, position);
-    }
   }
 
-  sprintf(str_path,"%d\0",count);
-  path = gtk_tree_path_new_from_string (str_path);
-  gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
-  g_signal_stop_emission_by_name(G_OBJECT(event_viewer_data->tree_v), "cursor-changed");
-  gtk_tree_path_free(path);  
 
   return FALSE;
 }
 
+
+
 gboolean traceset_changed(void * hook_data, void * call_data)
 {
   EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
-  LttTime start;
-  
-  remove_all_items_from_queue(event_viewer_data->raw_trace_data_queue);
+  LttvTracesetContext * tsc =
+        lttvwindow_get_traceset_context(event_viewer_data->tab);
+  TimeInterval time_span = tsc->time_span;
+  LttTime end;
   gtk_list_store_clear(event_viewer_data->store_m);
-  event_viewer_data->shown = FALSE;
-  event_viewer_data->append = TRUE;
-
-  get_traceset_time_span(event_viewer_data->mw, &event_viewer_data->time_span);
-  start = ltt_time_sub(event_viewer_data->time_span.endTime, event_viewer_data->time_span.startTime);
-  event_viewer_data->vadjust_c->upper = ltt_time_to_double(start) * NANOSECONDS_PER_SECOND;
+  g_ptr_array_set_size(event_viewer_data->pos, 0);
+
+  end = ltt_time_sub(time_span.end_time, time_span.start_time);
+  event_viewer_data->vadjust_c->upper = ltt_time_to_double(end);
+
+  /* Reset the positions */
+  lttv_traceset_context_position_destroy(
+      event_viewer_data->currently_selected_position);
+  lttv_traceset_context_position_destroy(
+      event_viewer_data->first_event);
+  lttv_traceset_context_position_destroy(
+      event_viewer_data->last_event);
+  event_viewer_data->currently_selected_position =
+    lttv_traceset_context_position_new(tsc);
+  event_viewer_data->first_event =
+    lttv_traceset_context_position_new(tsc);
+  event_viewer_data->last_event =
+    lttv_traceset_context_position_new(tsc);
+
+  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;
 }
 
-
-void tree_v_grab_focus(GtkWidget *widget, gpointer data){
-  EventViewerData *event_viewer_data = (EventViewerData *)data;
-  MainWindow * mw = event_viewer_data->mw;
-  set_focused_pane(mw, gtk_widget_get_parent(event_viewer_data->hbox_v));
-}
-
-void update_raw_data_array(EventViewerData* event_viewer_data, unsigned size)
-{
-  RawTraceData * data;
-  if(size > 0){
-    int pid, tmpPid, i,j,len;
-    GList * list, *tmpList;
-    GArray * pid_array, * tmp_pid_array;
-    
-    pid_array     = g_array_sized_new(FALSE, TRUE, sizeof(int), 10);
-    tmp_pid_array = g_array_sized_new(FALSE, TRUE, sizeof(int), 10);
-
-    //if the queue is full, remove some data, keep the size of the queue constant
-    while(event_viewer_data->raw_trace_data_queue->length + size > RESERVE_BIG_SIZE){
-      remove_item_from_queue(event_viewer_data->raw_trace_data_queue,
-           event_viewer_data->append);
-    }
-
-    //update pid if it is not known
-    if(event_viewer_data->raw_trace_data_queue->length > 0){
-      list    = event_viewer_data->raw_trace_data_queue->head;
-      tmpList = event_viewer_data->raw_trace_data_queue_tmp->head;
-      if(event_viewer_data->append){
-  for(i= event_viewer_data->raw_trace_data_queue->length-1;i>=0;i--){
-    data = (RawTraceData*)g_list_nth_data(list,i);
-    len = data->pid==0 ? -2 : data->pid;
-    if(data->cpu_id+1 > pid_array->len){
-      pid_array = g_array_set_size(pid_array,data->cpu_id+1);     
-      pid_array = g_array_insert_val(pid_array,data->cpu_id,len);
-      pid_array = g_array_remove_index(pid_array,data->cpu_id+1);
-    }else if(data->cpu_id+1 < pid_array->len){
-      pid = g_array_index(pid_array,int,data->cpu_id);
-      if(pid == 0){
-        pid_array = g_array_insert_val(pid_array,data->cpu_id,len);
-        pid_array = g_array_remove_index(pid_array,data->cpu_id+1);
-      }
-    }   
-  }
-
-  for(i=0;i<event_viewer_data->raw_trace_data_queue_tmp->length;i++){
-    data = (RawTraceData*)g_list_nth_data(tmpList,i);
-    len = data->pid==0 ? -2 : data->pid;
-    if(data->cpu_id+1 > tmp_pid_array->len){
-      tmp_pid_array = g_array_set_size(tmp_pid_array,data->cpu_id+1);     
-      tmp_pid_array = g_array_insert_val(tmp_pid_array,data->cpu_id,len);
-      tmp_pid_array = g_array_remove_index(tmp_pid_array,data->cpu_id+1);
-    }else if(data->cpu_id+1 < tmp_pid_array->len){
-      pid = g_array_index(tmp_pid_array,int,data->cpu_id);
-      if(pid == 0){
-        tmp_pid_array = g_array_insert_val(tmp_pid_array,data->cpu_id,len);
-        tmp_pid_array = g_array_remove_index(tmp_pid_array,data->cpu_id+1);
-      }
-    }   
-  }
-      }else{
-  for(i=0;i<event_viewer_data->raw_trace_data_queue->length;i++){
-    data = (RawTraceData*)g_list_nth_data(list,i);
-    len = data->pid==0 ? -2 : data->pid;
-    if(data->cpu_id+1 > pid_array->len){
-      pid_array = g_array_set_size(pid_array,data->cpu_id+1);     
-      pid_array = g_array_insert_val(pid_array,data->cpu_id,len);
-      pid_array = g_array_remove_index(pid_array,data->cpu_id+1);
-    }else if(data->cpu_id+1 < pid_array->len){
-      pid = g_array_index(pid_array,int,data->cpu_id);
-      if(pid == 0){
-        pid_array = g_array_insert_val(pid_array,data->cpu_id,len);
-        pid_array = g_array_remove_index(pid_array,data->cpu_id+1);
-      }
-    }   
-  }
-
-  for(i=event_viewer_data->raw_trace_data_queue_tmp->length-1;i>=0;i--){
-    data = (RawTraceData*)g_list_nth_data(tmpList,i);
-    len = data->pid==0 ? -2 : data->pid;
-    if(data->cpu_id+1 > tmp_pid_array->len){
-      tmp_pid_array = g_array_set_size(tmp_pid_array,data->cpu_id+1);     
-      tmp_pid_array = g_array_insert_val(tmp_pid_array,data->cpu_id,len);
-      tmp_pid_array = g_array_remove_index(tmp_pid_array,data->cpu_id+1);
-    }else if(data->cpu_id+1 < tmp_pid_array->len){
-      pid = g_array_index(tmp_pid_array,int,data->cpu_id);
-      if(pid == 0){
-        tmp_pid_array = g_array_insert_val(tmp_pid_array,data->cpu_id,len);
-        tmp_pid_array = g_array_remove_index(tmp_pid_array,data->cpu_id+1);
-      }
-    }   
-  }
-      }
-      
-      len = pid_array->len > tmp_pid_array->len ? tmp_pid_array->len : pid_array->len;
-      for(j=0;j<len;j++){
-  pid = g_array_index(pid_array,int, j);
-  tmpPid = g_array_index(tmp_pid_array,int,j);
-  if(pid == -2)pid = 0;
-  if(tmpPid == -2) tmpPid = 0;
-  
-  if(pid == -1 && tmpPid != -1){
-    for(i=0;i<event_viewer_data->raw_trace_data_queue->length;i++){
-      data = (RawTraceData*)g_list_nth_data(list,i);
-      if(data->pid == -1 && data->cpu_id == j) data->pid = tmpPid;
-    }
-  }else if(pid != -1 && tmpPid == -1){
-    for(i=0;i<event_viewer_data->raw_trace_data_queue_tmp->length;i++){
-      data = (RawTraceData*)g_list_nth_data(tmpList,i);
-      if(data->pid == -1 && data->cpu_id == j) data->pid = pid;
-    }
-  }
-      }
-    }
-
-    g_array_free(pid_array,TRUE);
-    g_array_free(tmp_pid_array, TRUE);
-
-    //add data from tmp queue into the queue
-    event_viewer_data->number_of_events = event_viewer_data->raw_trace_data_queue->length 
-                                        + event_viewer_data->raw_trace_data_queue_tmp->length;
-    if(event_viewer_data->append){
-      if(event_viewer_data->raw_trace_data_queue->length > 0)
-  event_viewer_data->current_event_index = event_viewer_data->raw_trace_data_queue->length - 1;
-      else event_viewer_data->current_event_index = 0;
-      while((data = g_queue_pop_head(event_viewer_data->raw_trace_data_queue_tmp)) != NULL){
-  g_queue_push_tail(event_viewer_data->raw_trace_data_queue, data);
-      }
-    }else{
-      event_viewer_data->current_event_index += event_viewer_data->raw_trace_data_queue_tmp->length;
-      while((data = g_queue_pop_tail(event_viewer_data->raw_trace_data_queue_tmp)) != NULL){
-  g_queue_push_head(event_viewer_data->raw_trace_data_queue, data);
-      }
-    }
-  }
-}
-
-void get_events(EventViewerData* event_viewer_data, LttTime start, 
-    LttTime end,unsigned max_num_events, unsigned * real_num_events)
+gboolean filter_changed(void * hook_data, void * call_data)
 {
-  int size;
-  LttvTracesetContext * tsc = get_traceset_context(event_viewer_data->mw);
-
-  //  context_add_hooks_api(event_viewer_data->mw, NULL, NULL, NULL, NULL, NULL, NULL,
-  //      NULL, NULL, NULL,event_viewer_data->before_event_hooks,NULL);
-  add_context_hooks(event_viewer_data,tsc);
-
-  process_traceset_api(event_viewer_data->mw, start, end, max_num_events);
+  EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
+  LttvTracesetContext * tsc =
+        lttvwindow_get_traceset_context(event_viewer_data->tab);
 
-  remove_context_hooks(event_viewer_data,tsc);
-  //  context_remove_hooks_api(event_viewer_data->mw, NULL, NULL, NULL, NULL, NULL, NULL,
-  //         NULL, NULL, NULL,event_viewer_data->before_event_hooks,NULL);
+  event_viewer_data->main_win_filter = 
+    (LttvFilter*)call_data;
+  get_events(event_viewer_data->vadjust_c->value, event_viewer_data);
 
-  size = event_viewer_data->raw_trace_data_queue_tmp->length;
-  *real_num_events = size;
-  
-  update_raw_data_array(event_viewer_data,size);
+  return FALSE;
 }
 
-static void get_event_detail(LttEvent *e, LttField *f, GString * s)
-{
-  LttType *type;
-  LttField *element;
-  char *name;
-  int nb, i;
-
-  type = ltt_field_type(f);
-  switch(ltt_type_class(type)) {
-    case LTT_INT:
-      g_string_append_printf(s, " %ld", ltt_event_get_long_int(e,f));
-      break;
-
-    case LTT_UINT:
-      g_string_append_printf(s, " %lu", ltt_event_get_long_unsigned(e,f));
-      break;
-
-    case LTT_FLOAT:
-      g_string_append_printf(s, " %g", ltt_event_get_double(e,f));
-      break;
-
-    case LTT_STRING:
-      g_string_append_printf(s, " \"%s\"", ltt_event_get_string(e,f));
-      break;
-
-    case LTT_ENUM:
-      g_string_append_printf(s, " %s", ltt_enum_string_get(type,
-          ltt_event_get_unsigned(e,f)-1));
-      break;
-
-    case LTT_ARRAY:
-    case LTT_SEQUENCE:
-      g_string_append_printf(s, " {");
-      nb = ltt_event_field_element_number(e,f);
-      element = ltt_field_element(f);
-      for(i = 0 ; i < nb ; i++) {
-        ltt_event_field_element_select(e,f,i);
-  get_event_detail(e, element, s);
-      }
-      g_string_append_printf(s, " }");
-      break;
-
-    case LTT_STRUCT:
-      g_string_append_printf(s, " {");
-      nb = ltt_type_member_number(type);
-      for(i = 0 ; i < nb ; i++) {
-        element = ltt_field_member(f,i);
-  ltt_type_member_type(type, i, &name);
-  g_string_append_printf(s, " %s = ", name);        
-        get_event_detail(e, element, s);
-      }
-      g_string_append_printf(s, " }");
-      break;
-  }
-  
-}
 
-static void get_pid(unsigned * in, unsigned * out, char * s)
+gint evd_redraw_notify(void *hook_data, void *call_data)
 {
-  char * str;
-  str = strstr(s, "out =");
-  if (str){
-    str = str + 5;
-    sscanf(str,"%d", out);
-  }else{
-    g_warning("Can not find out pid\n");
-  }
+  EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
 
-  str = strstr(s,"in =");
-  if (str){
-    str = str + 4;
-    sscanf(str,"%d", in);
-  }else{
-    g_warning("Can not find in pid\n");
-  }
+  get_events(event_viewer_data->vadjust_c->value, event_viewer_data);
+  return 0;
 }
 
-gboolean parse_event(void *hook_data, void *call_data)
+void gui_events_free(gpointer data)
 {
-  EventViewerData *event_viewer_data = (EventViewerData *)hook_data;
-  LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
-  LttvTracefileState *tfs = (LttvTracefileState *)call_data;
-
-  RawTraceData * tmp_raw_trace_data,*prev_raw_trace_data = NULL, *data=NULL;
-  LttEvent *e;
-  LttTime time;
-  LttField * field;
-  unsigned in=0, out=0;
-  int i;
-  GString * detail_event = g_string_new("");
-  GList * list;
-
-  e = tfc->e;
-  field = ltt_event_field(e);
-  time = ltt_event_time(e);
-
-  tmp_raw_trace_data = g_new(RawTraceData,1);
-  tmp_raw_trace_data->cpu_id = ltt_event_cpu_id(e);
-  tmp_raw_trace_data->event_name = g_strdup(ltt_eventtype_name(ltt_event_eventtype(e)));
-  tmp_raw_trace_data->time = time;
-  tmp_raw_trace_data->ep = ltt_event_position_new();
-
-  if(event_viewer_data->raw_trace_data_queue_tmp->length){ 
-    list = event_viewer_data->raw_trace_data_queue_tmp->head;
-    for(i=event_viewer_data->raw_trace_data_queue_tmp->length-1;i>=0;i--){
-      data = (RawTraceData *)g_list_nth_data(list,i);
-      if(data->cpu_id == tmp_raw_trace_data->cpu_id){
-  prev_raw_trace_data = data;
-  break;
-      }
-    }    
-  }  
-
-  if(prev_raw_trace_data) tmp_raw_trace_data->pid = prev_raw_trace_data->pid;
-  else tmp_raw_trace_data->pid = -1;
+  LttvPluginEVD *plugin_evd = (LttvPluginEVD*)data;
+  Tab *tab = plugin_evd->evd->tab;
+  EventViewerData *event_viewer_data = plugin_evd->evd;
+  guint i;
+  lttv_filter_destroy(plugin_evd->evd->filter);
 
-  tmp_raw_trace_data->entry_length = field == NULL ? 0 : ltt_field_size(field);
-  if(field) get_event_detail(e, field, detail_event);
-  tmp_raw_trace_data->event_description  = g_strdup(detail_event->str);
+  if(tab != NULL){
+    lttv_hooks_remove(event_viewer_data->event_hooks,event_hook);
+    lttv_hooks_destroy(event_viewer_data->event_hooks);
+    
+    for(i=0;i<event_viewer_data->pos->len;i++) {
+      LttvTracesetContextPosition *cur_pos = 
+        (LttvTracesetContextPosition*)g_ptr_array_index(event_viewer_data->pos,
+                                                        i);
+      lttv_traceset_context_position_destroy(cur_pos);
+    }
+    lttv_traceset_context_position_destroy(
+        event_viewer_data->currently_selected_position);
+    lttv_traceset_context_position_destroy(
+        event_viewer_data->first_event);
+    lttv_traceset_context_position_destroy(
+        event_viewer_data->last_event);
+    g_ptr_array_free(event_viewer_data->pos, TRUE);
+    
+    lttvwindow_unregister_current_time_notify(tab,
+                        update_current_time, event_viewer_data);
+    lttvwindow_unregister_current_position_notify(tab,
+                        update_current_position, event_viewer_data);
+    //lttvwindow_unregister_show_notify(tab,
+    //                    show_event_detail, event_viewer_data);
+    lttvwindow_unregister_traceset_notify(tab,
+                        traceset_changed, event_viewer_data);
+    lttvwindow_unregister_filter_notify(tab,
+                        filter_changed, event_viewer_data);
+    lttvwindow_unregister_redraw_notify(tab,
+                evd_redraw_notify, event_viewer_data);
 
-  if(strcmp(tmp_raw_trace_data->event_name, "schedchange") == 0){
-    get_pid(&in, &out, detail_event->str);
   }
+  lttvwindowtraces_background_notify_remove(event_viewer_data);
 
+  g_event_viewer_data_list = g_slist_remove(g_event_viewer_data_list,
+      event_viewer_data);
+  //g_free(event_viewer_data);
+  g_object_unref(plugin_evd);
+}
 
-  if(in != 0 || out != 0){
-    tmp_raw_trace_data->pid = in;
-    if(prev_raw_trace_data && prev_raw_trace_data->pid == -1){
-      list = event_viewer_data->raw_trace_data_queue_tmp->head;
-      for(i=0;i<event_viewer_data->raw_trace_data_queue_tmp->length;i++){
-  data = (RawTraceData *)g_list_nth_data(list,i);
-  if(data->cpu_id == tmp_raw_trace_data->cpu_id){
-    data->pid = out;
-  }
-      }
-    }
-  }
-  
-  ltt_event_position(e, tmp_raw_trace_data->ep);
-
-  if(event_viewer_data->raw_trace_data_queue_tmp->length >= RESERVE_SMALL_SIZE){
-    if(event_viewer_data->append){
-      list = g_list_last(event_viewer_data->raw_trace_data_queue_tmp->head);
-      data = (RawTraceData *)(list->data);
-      if(data->time.tv_sec  == time.tv_sec &&
-   data->time.tv_nsec == time.tv_nsec){
-  g_queue_push_tail(event_viewer_data->raw_trace_data_queue_tmp,tmp_raw_trace_data);      
-      }else{
-  g_free(tmp_raw_trace_data);          
-      }
-    }else{
-      remove_item_from_queue(event_viewer_data->raw_trace_data_queue_tmp,TRUE);
-      g_queue_push_tail(event_viewer_data->raw_trace_data_queue_tmp,tmp_raw_trace_data);      
-    }
-  }else{
-    g_queue_push_tail (event_viewer_data->raw_trace_data_queue_tmp,tmp_raw_trace_data);
-  }
-
-  g_string_free(detail_event, TRUE);
 
-  return FALSE;
-}
 
-void remove_item_from_queue(GQueue * q, gboolean fromHead)
+void gui_events_destructor(gpointer data)
 {
-  RawTraceData *data1, *data2 = NULL;
-  GList * list;
-
-  if(fromHead){
-    data1 = (RawTraceData *)g_queue_pop_head(q);
-    list  = g_list_first(q->head);
-    if(list)
-      data2 = (RawTraceData *)(list->data);
-  }else{
-    data1 = (RawTraceData *)g_queue_pop_tail(q);
-    list  = g_list_last(q->head);
-    if(list)
-      data2 = (RawTraceData *)(list->data);
-  }
-
-  if(data2){
-    if(data1->time.tv_sec  == data2->time.tv_sec &&
-       data1->time.tv_nsec == data2->time.tv_nsec){
-      remove_item_from_queue(q, fromHead);
-    }
+  LttvPluginEVD *plugin_evd = (LttvPluginEVD*)data;
+  /* May already been done by GTK window closing */
+  if(GTK_IS_WIDGET(plugin_evd->parent.top_widget)){
+    gtk_widget_destroy(plugin_evd->parent.top_widget);
   }
-
-  g_free(data1);
-
-  return;
 }
 
-void remove_all_items_from_queue(GQueue *q)
-{
-  RawTraceData *data;
-  while((data = (RawTraceData *)g_queue_pop_head(q)) != NULL){
-    g_free(data);
-  }  
-}
 
 
 /**
@@ -1844,17 +1887,17 @@ void remove_all_items_from_queue(GQueue *q)
  */
 static void init() {
 
-  /* Register the toolbar insert button */
-  toolbar_item_reg(hGuiEventsInsert_xpm, "Insert Event Viewer", h_gui_events);
-  
-  /* Register the menu item insert entry */
-  menu_item_reg("/", "Insert Event Viewer", h_gui_events);
-  
+  lttvwindow_register_constructor("guievents",
+                                  "/",
+                                  "Insert Event Viewer",
+                                  hGuiEventsInsert_xpm,
+                                  "Insert Event Viewer",
+                                  h_gui_events);
 }
 
 void event_destroy_walk(gpointer data, gpointer user_data)
 {
-  gui_events_destructor((EventViewerData*)data);
+  gui_events_destructor((LttvPluginEVD*)data);
 }
 
 /**
@@ -1864,23 +1907,17 @@ void event_destroy_walk(gpointer data, gpointer user_data)
  * everything that has been registered in the gtkTraceSet API.
  */
 static void destroy() {
-  int i;
-  
-  EventViewerData *event_viewer_data;
   
-  if(g_event_viewer_data_list){
-    g_slist_foreach(g_event_viewer_data_list, event_destroy_walk, NULL );
-    g_slist_free(g_event_viewer_data_list);
-  }
+  g_slist_foreach(g_event_viewer_data_list, event_destroy_walk, NULL );
+  g_slist_free(g_event_viewer_data_list);
 
-  /* Unregister the toolbar insert button */
-  toolbar_item_unreg(h_gui_events);
+  lttvwindow_unregister_constructor(h_gui_events);
   
-  /* Unregister the menu item insert entry */
-  menu_item_unreg(h_gui_events);
 }
 
 
+
+
 LTTV_MODULE("guievents", "Detailed events view", \
     "Graphical module to display a detailed event list", \
-           init, destroy, "mainwin")
+           init, destroy, "lttvwindow", "print")
This page took 0.05449 seconds and 4 git commands to generate.