viewer -> lttvwindow name change
authorcompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Mon, 14 Jun 2004 20:01:13 +0000 (20:01 +0000)
committercompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Mon, 14 Jun 2004 20:01:13 +0000 (20:01 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@591 04897980-b3bd-0310-b5e0-8ef037075253

ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/Makefile.am
ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c
ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/gtkmultivpaned.c
ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.c [new file with mode: 0644]
ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h [new file with mode: 0644]
ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/menu.h
ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/toolbar.h

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