Add Histogram
authorcompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Fri, 17 Mar 2006 17:59:20 +0000 (17:59 +0000)
committercompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Fri, 17 Mar 2006 17:59:20 +0000 (17:59 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@1710 04897980-b3bd-0310-b5e0-8ef037075253

18 files changed:
ltt/branches/poly/configure.in
ltt/branches/poly/lttv/modules/gui/Makefile.am
ltt/branches/poly/lttv/modules/gui/histogram/Makefile.am [new file with mode: 0644]
ltt/branches/poly/lttv/modules/gui/histogram/hHistogramInsert.xpm [new file with mode: 0644]
ltt/branches/poly/lttv/modules/gui/histogram/histobuttonwidget.c [new file with mode: 0644]
ltt/branches/poly/lttv/modules/gui/histogram/histobuttonwidget.h [new file with mode: 0644]
ltt/branches/poly/lttv/modules/gui/histogram/histocfv.c [new file with mode: 0644]
ltt/branches/poly/lttv/modules/gui/histogram/histocfv.h [new file with mode: 0644]
ltt/branches/poly/lttv/modules/gui/histogram/histodrawing.c [new file with mode: 0644]
ltt/branches/poly/lttv/modules/gui/histogram/histodrawing.h [new file with mode: 0644]
ltt/branches/poly/lttv/modules/gui/histogram/histodrawitem.c [new file with mode: 0644]
ltt/branches/poly/lttv/modules/gui/histogram/histodrawitem.h [new file with mode: 0644]
ltt/branches/poly/lttv/modules/gui/histogram/histoeventhooks.c [new file with mode: 0644]
ltt/branches/poly/lttv/modules/gui/histogram/histoeventhooks.h [new file with mode: 0644]
ltt/branches/poly/lttv/modules/gui/histogram/histomodule.c [new file with mode: 0644]
ltt/branches/poly/lttv/modules/gui/histogram/stock_zoom_fit_24.xpm [new file with mode: 0644]
ltt/branches/poly/lttv/modules/gui/histogram/stock_zoom_in_24.xpm [new file with mode: 0644]
ltt/branches/poly/lttv/modules/gui/histogram/stock_zoom_out_24.xpm [new file with mode: 0644]

index 4c8d055768f123397b8709d88180dc2ef663d484..b25407a54d8c32ff21b3c9c51a41fdaff58fb3ca 100644 (file)
@@ -23,7 +23,7 @@
 AC_PREREQ(2.57)
 AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
 #AC_WITH_LTDL  # not needed ?
-AM_INIT_AUTOMAKE(LinuxTraceToolkitViewer,0.8.33-12032006)
+AM_INIT_AUTOMAKE(LinuxTraceToolkitViewer,0.8.34-17032006)
 AM_CONFIG_HEADER(config.h)
 AM_PROG_LIBTOOL
 
@@ -125,6 +125,7 @@ AC_CONFIG_FILES([Makefile
                 lttv/modules/gui/controlflow/Makefile
                 lttv/modules/gui/detailedevents/Makefile
                 lttv/modules/gui/statistics/Makefile
+                lttv/modules/gui/histogram/Makefile
      lttv/modules/gui/filter/Makefile
      lttv/modules/gui/tracecontrol/Makefile
                 ltt/Makefile
index ee483f4bb98ef0634fcab154147ff4430b087c25..82efa56715d8b69387771538c23e69cbb4510ef8 100644 (file)
@@ -6,7 +6,7 @@
 
 # WARNING : subdirs order is important : mainWin depends on API
 
-SUBDIRS = lttvwindow controlflow detailedevents statistics filter tracecontrol interrupts diskperformance
+SUBDIRS = lttvwindow controlflow detailedevents statistics filter tracecontrol interrupts diskperformance histogram
 
 
 
diff --git a/ltt/branches/poly/lttv/modules/gui/histogram/Makefile.am b/ltt/branches/poly/lttv/modules/gui/histogram/Makefile.am
new file mode 100644 (file)
index 0000000..69045fd
--- /dev/null
@@ -0,0 +1,42 @@
+# This file is part of the Linux Trace Toolkit viewer
+# Copyright (C) 2003-2004 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.
+
+
+
+#
+# Makefile for LTT New generation user interface : plugins.
+#
+# Created by Mathieu Desnoyers on May 6, 2003
+#
+
+AM_CFLAGS = $(GLIB_CFLAGS) 
+AM_CFLAGS += $(GTK_CFLAGS)
+LIBS += $(GLIB_LIBS)
+LIBS += $(GTK_LIBS) -L${top_srcdir}/lttv/modules/gui/lttvwindow/lttvwindow -llttvwindow
+
+libdir = ${lttvplugindir}
+
+lib_LTLIBRARIES = libguihistogram.la
+libguihistogram_la_LDFLAGS = -module
+libguihistogram_la_SOURCES = histomodule.c histoeventhooks.c histocfv.c \
+                       histobuttonwidget.c histodrawing.c histodrawitem.c 
+
+noinst_HEADERS = histoeventhooks.h histocfv.h \
+               histobuttonwidget.h histodrawing.h histodrawitem.h   
+
+EXTRA_DIST = \
+               hHistogramInsert.xpm stock_zoom_in_24.xpm stock_zoom_out_24.xpm \                       stock_zoom_fit_24.xpm
diff --git a/ltt/branches/poly/lttv/modules/gui/histogram/hHistogramInsert.xpm b/ltt/branches/poly/lttv/modules/gui/histogram/hHistogramInsert.xpm
new file mode 100644 (file)
index 0000000..ba18fed
--- /dev/null
@@ -0,0 +1,35 @@
+/* XPM */
+static char *hHistogramInsert_xpm[]={
+"22 22 10 1",
+"b c None",
+". c None",
+"f c #0000c0",
+"e c #0000ff",
+"g c #004000",
+"d c #008080",
+"a c #00ff00",
+"c c #800000",
+"# c #808000",
+"h c #ffff00",
+"......................",
+"####aaaaaaaaaaaaaaaaaa",
+".....bbbbbb####b......",
+"...ccccbbbccccb#b#..##",
+"....cc.bbbbcc.b.#.#.#.",
+"....cc..bbbcc..ddd.#..",
+"....cc..bbbcc.dd.dd...",
+"....cc..bbbcc.d...d...",
+"....cc..bbbcceeee.dfff",
+"....ccccccccc.d...d...",
+"....cc..bbbccd....dd..",
+"....cc..bbbcc...eeee..",
+"....cc..bbbcc......dd.",
+"...#cc#####cc.......dd",
+"....cc.bbbbcc..bbbbb..",
+"...cccc.bbcccc.bbbbb..",
+"....bbggbbbbb.ggbbbb..",
+"hhhh.ghhghbbbghhghbbhh",
+"g.bbbgbbgbbbbgbbg..b..",
+"gbbbbgbbgbbbbgbbg..bbg",
+".gbhhhhbbghhghb..ghhgb",
+"bbgg...b..gg......gg.."};
diff --git a/ltt/branches/poly/lttv/modules/gui/histogram/histobuttonwidget.c b/ltt/branches/poly/lttv/modules/gui/histogram/histobuttonwidget.c
new file mode 100644 (file)
index 0000000..279be94
--- /dev/null
@@ -0,0 +1,246 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2006 Parisa Heidari
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "histobuttonwidget.h"
+#include "histodrawing.h"
+#include "histodrawitem.h"
+#include "stock_zoom_in_24.xpm"
+#include "stock_zoom_out_24.xpm"
+#include "stock_zoom_fit_24.xpm"
+
+#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
+#define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
+
+/* Preallocated Size of the index_to_pixmap array */
+#define ALLOCATE_PROCESSES 1000
+
+/*****************************************************************************
+ *                                       *
+ *****************************************************************************/
+static GtkWidget *xpm_label_box( gchar     *xpm_filename,
+                                 gchar     *label_text );
+static gboolean gplus( GtkWidget *widget,gpointer user_data)
+{
+  HistoControlFlowData *histo_cfd =  (HistoControlFlowData *)user_data;
+  //histo_cfd->vertical_ratio =histo_cfd->vertical_ratio * (1.0/2.0);  
+  if(histo_cfd->max_height>1)
+  {
+       histo_cfd->max_height /= 2;
+   //just redraw.horizontal scale is not changed so Array's data are valid.
+       histogram_show(histo_cfd ,0,histo_cfd->number_of_process->len);
+  }
+  else
+       g_warning("Zoom more than 1 event is impossible");
+       
+  histo_drawing_update_vertical_ruler(histo_cfd->drawing);//, TimeWindow *time_window);
+  return 0;
+}
+
+static gboolean gMinus( GtkWidget *widget,
+                   gpointer user_data )
+{
+  HistoControlFlowData *histo_cfd = (HistoControlFlowData *)user_data;
+  histo_cfd->max_height *= 2;
+  //just redraw.horizontal scale is not changed so Array's data are valid.
+  histogram_show(histo_cfd ,0,histo_cfd->number_of_process->len);
+  histo_drawing_update_vertical_ruler(histo_cfd->drawing);//, TimeWindow *time_window);
+  return 0;
+}
+
+static gboolean gFit( GtkWidget *widget,
+                   gpointer user_data )
+{
+  /*find the maximum value and put max_height equal with this maximum*/
+  HistoControlFlowData *histo_cfd = (HistoControlFlowData *)user_data;
+  gint i=1,x;
+  guint maximum;
+  maximum =g_array_index(histo_cfd->number_of_process,guint,i);
+  for (i=1; i < histo_cfd->number_of_process-> len ;i++)
+  {
+       x=g_array_index(histo_cfd->number_of_process,guint,i);
+       maximum=MAX(x,maximum);
+  }
+  if (maximum >0)
+  {
+       histo_cfd->max_height=maximum;
+        histogram_show (histo_cfd,0,histo_cfd->number_of_process->len);
+  }
+  histo_drawing_update_vertical_ruler(histo_cfd->drawing);
+  
+  return 0;
+}
+/* Create a new hbox with an image and a label packed into it
+ * and return the box. */
+
+static GtkWidget *xpm_label_box( gchar* xpm_filename,
+                                 gchar     *label_text )
+{
+    GtkWidget *box;
+    GtkWidget *label;
+    GtkWidget *image;
+
+    GdkPixbuf *pixbufP;
+    //GError **error;
+    /* Create box for image and label */
+    box = gtk_hbox_new (FALSE, 0);
+    gtk_container_set_border_width (GTK_CONTAINER (box), 1);
+
+    /* Now on to the image stuff */
+        
+    pixbufP = gdk_pixbuf_new_from_xpm_data((const char*)xpm_filename);
+    image =  gtk_image_new_from_pixbuf(pixbufP);
+
+    /* Create a label for the button */
+    label = gtk_label_new (label_text);
+
+    /* Pack the image and label into the box */
+    gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 1);
+    gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 1);
+
+    gtk_widget_show (image);
+    gtk_widget_show (label);
+
+    return box;
+}
+
+ButtonWidget *histo_buttonwidget_construct(HistoControlFlowData *histocontrol_flow_data)
+{
+  GtkWidget *boxPlus, *boxMinus , *boxfit;//containing text and image for each button.
+
+  ButtonWidget *buttonwidget = g_new(ButtonWidget,1);
+  buttonwidget->histo_control_flow_data = histocontrol_flow_data;
+  /* Put + and - on the vbox and assign related functions to each button */
+  buttonwidget-> vbox1 = gtk_vbox_new (FALSE, 0);
+  
+// Add 2 buttons on the vbox 
+//  buttonwidget ->buttonP = gtk_button_new_with_mnemonic ("+");
+//  buttonwidget->buttonM = gtk_button_new_with_mnemonic ("-");
+// Instead, add 2 button with image and text:
+
+  buttonwidget ->buttonP =gtk_button_new ();
+  buttonwidget ->buttonM =gtk_button_new ();
+  buttonwidget ->buttonFit =gtk_button_new ();
+
+/* This calls our box creating function */
+  boxPlus = xpm_label_box (stock_zoom_in_24, "vertical");
+  boxMinus = xpm_label_box (stock_zoom_out_24, "vertical");
+  boxfit = xpm_label_box (stock_zoom_fit_24, "vertical");
+
+/* Pack and show all widgets */
+  gtk_widget_show (boxPlus);
+  gtk_widget_show (boxMinus);
+  gtk_widget_show (boxfit);
+
+  gtk_container_add (GTK_CONTAINER (buttonwidget -> buttonP), boxPlus);
+  gtk_container_add (GTK_CONTAINER (buttonwidget -> buttonM), boxMinus);
+  gtk_container_add (GTK_CONTAINER (buttonwidget -> buttonFit), boxfit);
+
+  gtk_box_pack_start (GTK_BOX (buttonwidget->vbox1),buttonwidget->buttonP, TRUE, FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (buttonwidget->vbox1),buttonwidget->buttonM, TRUE, FALSE, 0);
+  gtk_box_pack_end (GTK_BOX (buttonwidget->vbox1),buttonwidget->buttonFit, TRUE, FALSE, 0);
+
+    /* When the button receives the "clicked" signal, it will call the
+     * function gplus() passing it NULL as its argument.  The gplus()
+     * function is defined above . */
+
+    g_signal_connect (G_OBJECT (buttonwidget ->buttonP), "clicked",
+               G_CALLBACK (gplus), (gpointer)histocontrol_flow_data);
+    g_signal_connect (G_OBJECT ( buttonwidget->buttonM), "clicked",
+               G_CALLBACK (gMinus), (gpointer)histocontrol_flow_data);
+    g_signal_connect (G_OBJECT ( buttonwidget->buttonFit), "clicked",
+               G_CALLBACK (gFit), (gpointer)histocontrol_flow_data);
+
+  gtk_widget_show (buttonwidget -> vbox1);
+  gtk_widget_show (buttonwidget ->buttonP);
+  gtk_widget_show (buttonwidget ->buttonM);
+  gtk_widget_show (buttonwidget ->buttonFit);
+
+  return buttonwidget;
+}
+
+void histo_buttonwidget_destroy(ButtonWidget *buttonwidget)
+{
+  g_debug("buttonwidget_destroy %p", buttonwidget);
+  
+  g_free(buttonwidget);
+  g_debug("buttonwidget_destroy end");
+}
+
+GtkWidget *histo_buttonwidget_get_widget(ButtonWidget *button_widget)
+{
+  return button_widget->vbox1;
+}
+
+
+
+void histo_rectangle_pixmap (GdkGC *gc,
+    gboolean filled, gint x, gint y, gint width, gint height,
+                                  histoDrawing_t *value)
+{
+  if(height == -1)
+    height = value->drawing_area->allocation.height;
+  if(width == -1)
+    height = value->drawing_area->allocation.width; 
+  gdk_draw_rectangle (value->pixmap,
+      gc,
+      filled,
+      x, y,
+      width, height);
+}
+
+//This could be usefull if a vertical scroll bar is added to viewer:
+void histo_copy_pixmap_region(histoDrawing_t *drawing,GdkDrawable *dest,
+    GdkGC *gc, GdkDrawable *src,
+    gint xsrc, gint ysrc,
+    gint xdest, gint ydest, gint width, gint height)
+{
+
+  if(dest == NULL)
+    dest = drawing->pixmap;
+  if(src == NULL)
+    src = drawing->pixmap;
+
+  gdk_draw_drawable (dest,gc,src,xsrc, ysrc,
+      xdest, ydest,width, height);
+}
+
+void histo_update_pixmap_size(histoDrawing_t *value,
+                                    guint width)
+{
+  GdkPixmap *old_pixmap = value->pixmap;
+
+  value->pixmap = 
+        gdk_pixmap_new(old_pixmap,
+                       width,
+                       value->height,
+                       -1);
+
+  gdk_pixmap_unref(old_pixmap);
+}
+
diff --git a/ltt/branches/poly/lttv/modules/gui/histogram/histobuttonwidget.h b/ltt/branches/poly/lttv/modules/gui/histogram/histobuttonwidget.h
new file mode 100644 (file)
index 0000000..7c2ed88
--- /dev/null
@@ -0,0 +1,80 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2006 Parisa Heidari
+ *
+ * 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.
+ */
+
+#ifndef _HISTOBUTTONWIDGET_H
+#define _HISTOBUTTONWIDGET_H
+
+#include <gtk/gtk.h>
+#include <lttv/state.h>
+#include <ltt/ltt.h>
+#include "histocfv.h"
+#include "histodrawitem.h"
+
+
+/* The ButtonWidget
+ *
+ * Tasks :
+ * Create a widget
+ * containing 3 buttons zoomIn,zoonOut and zoomFit to change the vertical scale.
+ *
+ */
+#ifndef TYPE_ButtonWidget_DEFINED
+#define TYPE_ButtonWidget_DEFINED
+typedef struct _ButtonWidget ButtonWidget;
+#endif //TYPE_ButtonWidget_DEFINED
+
+#ifndef TYPE_HistoControlFlowData_DEFINED
+#define TYPE_HistoControlFlowData_DEFINED
+typedef struct _HistoControlFlowData HistoControlFlowData;
+#endif //TYPE_HistoControlFlowData_DEFINED
+
+struct _ButtonWidget {
+  
+  GtkWidget *buttonP;
+  GtkWidget *buttonM;
+  GtkWidget *buttonFit;
+
+  GtkWidget *vbox1;//buttons are placed on this vbox 
+
+  GtkWidget *hbox;//Parent Widget containing buttons and drawing area. 
+  HistoControlFlowData *histo_control_flow_data;
+
+};
+
+
+void histo_copy_pixmap_region(histoDrawing_t *drawing,GdkDrawable *dest, 
+    GdkGC *gc, GdkDrawable *src,
+    gint xsrc, gint ysrc,
+    gint xdest, gint ydest, gint width, gint height);
+
+void histo_rectangle_pixmap (GdkGC *gc,gboolean filled, gint x, gint y, 
+                       gint width, gint height,histoDrawing_t *value);
+
+ButtonWidget *histo_buttonwidget_construct(HistoControlFlowData *histocontrol_flow_data);
+
+void histo_buttonwidget_destroy(ButtonWidget *buttonwidget);
+
+
+static gboolean gplus( GtkWidget *widget,gpointer user_data);//assigned to zoomIn
+static gboolean gMinus( GtkWidget *widget,gpointer user_data );//assigned to zoomOut
+static gboolean gFit( GtkWidget *widget,gpointer user_data );//assigned to zoomFit
+
+GtkWidget *histo_buttonwidget_get_widget(ButtonWidget *button_widget);
+void histo_update_pixmap_size(histoDrawing_t *value,
+                                    guint width);
+#endif //_HISTOBUTTONWIDGET_H 
diff --git a/ltt/branches/poly/lttv/modules/gui/histogram/histocfv.c b/ltt/branches/poly/lttv/modules/gui/histogram/histocfv.c
new file mode 100644 (file)
index 0000000..32da15b
--- /dev/null
@@ -0,0 +1,242 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2006 Parisa heidari (inspired from CFV by 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <lttv/lttv.h>
+#include <lttvwindow/lttvwindow.h>
+
+#include "histocfv.h"
+#include "histodrawing.h"
+#include "histobuttonwidget.h"
+#include "histoeventhooks.h"
+
+#define PREDEFINED_HEIGHT 5000
+
+extern GSList *g_histo_control_flow_data_list;
+
+static gboolean
+header_size_allocate(GtkWidget *widget,
+                        GtkAllocation *allocation,
+                        gpointer user_data)
+{
+  histoDrawing_t *drawing = (histoDrawing_t*)user_data;
+
+  gtk_widget_set_size_request(drawing->ruler, -1, allocation->height);
+  //gtk_widget_queue_resize(drawing->padding);
+  //gtk_widget_queue_resize(drawing->ruler);
+  gtk_container_check_resize(GTK_CONTAINER(drawing->ruler_hbox));
+  return 0;
+}
+
+
+/*****************************************************************************
+ *              Histo Control Flow Viewer class implementation              *
+ *****************************************************************************/
+/**
+ * Histo Control Flow Viewer's constructor
+ *
+ * This constructor is given as a parameter to the menuitem and toolbar button
+ * registration. It creates the drawing widget.
+ * @param ParentWindow A pointer to the parent window.
+ * @return The widget created.
+ */
+HistoControlFlowData *
+guihistocontrolflow(Tab *tab)
+{
+  GtkWidget *button_widget, *drawing_widget, *drawing_area;
+  GtkWidget *buttonP,*buttonM;
+  histoDrawing_t *drawing;
+  HistoControlFlowData* histo_control_flow_data = g_new(HistoControlFlowData,1) ;
+  
+  
+  histo_control_flow_data->tab = tab;
+  histo_control_flow_data->max_height = PREDEFINED_HEIGHT;
+  /*histo_control_flow_data->v_adjust = 
+    GTK_ADJUSTMENT(gtk_adjustment_new(  0.0,  // Value 
+              0.0,  // Lower 
+              0.0,  // Upper 
+              0.0,  // Step inc. 
+              0.0,  // Page inc. 
+              0.0));  // page size */
+
+  // Create the drawing 
+  histo_control_flow_data->drawing = histo_drawing_construct(histo_control_flow_data);
+  
+  drawing = histo_control_flow_data->drawing;
+  drawing_widget = histo_drawing_get_widget(drawing);
+  
+  drawing_area = histo_drawing_get_drawing_area(drawing);
+
+  histo_control_flow_data->number_of_process = 0;
+  
+  ///histo_control_flow_data->background_info_waiting = 0;
+
+  // Create the Button widget 
+  histo_control_flow_data->buttonwidget = histo_buttonwidget_construct(histo_control_flow_data);
+  
+  button_widget = histo_buttonwidget_get_widget( histo_control_flow_data-> buttonwidget);
+  buttonP =histo_control_flow_data-> buttonwidget->buttonP;
+  buttonM =histo_control_flow_data-> buttonwidget->buttonM;
+
+  //set the size of ruler fix
+  gtk_widget_set_size_request(histo_control_flow_data->drawing->ruler, -1, 25);
+  gtk_container_check_resize(GTK_CONTAINER(histo_control_flow_data->drawing->ruler_hbox));
+
+/*//or set the size of ruler by button P
+  g_signal_connect (G_OBJECT(buttonP),
+        "size-allocate",
+        G_CALLBACK(header_size_allocate),
+        (gpointer)histo_control_flow_data->drawing);*/
+
+  ///histo_control_flow_data->h_paned = gtk_hpaned_new();
+
+  ///changed for histogram
+  histo_control_flow_data->box = gtk_hbox_new(FALSE, 0);
+  histo_control_flow_data->ev_box = gtk_event_box_new();
+
+ /// histo_control_flow_data->top_widget =gtk_event_box_new();
+  gtk_container_add(GTK_CONTAINER(histo_control_flow_data->ev_box),
+                       drawing_widget);
+ ///Now add button widget and drawing area on the top_widget.
+  gtk_box_pack_start (GTK_BOX (histo_control_flow_data->box),
+                       button_widget,FALSE,FALSE, 10);
+  gtk_box_pack_end (GTK_BOX (histo_control_flow_data->box),
+                       histo_control_flow_data->ev_box,TRUE,TRUE, 0);
+  histo_control_flow_data->top_widget = histo_control_flow_data->box;
+
+  /*gtk_container_add(GTK_CONTAINER(histo_control_flow_data->box),
+                    histo_control_flow_data->h_paned);
+      
+  gtk_paned_pack1(GTK_PANED(histo_control_flow_data->h_paned),
+                  button_widget->vbox1, FALSE, TRUE);
+  gtk_paned_pack2(GTK_PANED(histo_control_flow_data->h_paned),
+                  drawing_widget, TRUE, TRUE);
+  */
+  gtk_container_set_border_width(GTK_CONTAINER(histo_control_flow_data->ev_box), 1);
+  
+  // Set the size of the drawing area 
+  //drawing_Resize(drawing, h, w);
+
+  // Get trace statistics 
+  //histo_control_flow_data->Trace_Statistics = get_trace_statistics(Trace);
+
+  gtk_widget_show(drawing_widget);
+  gtk_widget_show(button_widget);
+  /*gtk_widget_show(histo_control_flow_data->h_paned);*/
+  gtk_widget_show(histo_control_flow_data->box);
+  gtk_widget_show(histo_control_flow_data->ev_box);
+  gtk_widget_show(histo_control_flow_data->top_widget);
+  g_object_set_data_full(
+      G_OBJECT(histo_control_flow_data->top_widget),
+      "histo_control_flow_data",
+      histo_control_flow_data,
+      (GDestroyNotify)guihistocontrolflow_destructor);
+    
+  g_object_set_data(
+      G_OBJECT(drawing_area),
+      "histo_control_flow_data",
+      histo_control_flow_data);
+        
+  g_histo_control_flow_data_list = g_slist_append(
+      g_histo_control_flow_data_list,
+      histo_control_flow_data);
+  histo_control_flow_data->number_of_process =g_array_new (FALSE,
+                                             TRUE,
+                                             sizeof(guint));
+  g_array_set_size (histo_control_flow_data->number_of_process,
+                                             drawing_area->allocation.width);
+  
+  //WARNING : The widget must be 
+  //inserted in the main window before the drawing area
+  //can be configured (and this must happend before sending
+  //data)
+  
+  return histo_control_flow_data;
+
+}
+
+/* Destroys widget also */
+void guihistocontrolflow_destructor_full(HistoControlFlowData *histo_control_flow_data)
+{
+  g_info("HISTOCFV.c : guihistocontrolflow_destructor_full, %p", histo_control_flow_data);
+  /* May already have been done by GTK window closing */
+  if(GTK_IS_WIDGET(guihistocontrolflow_get_widget(histo_control_flow_data)))
+    gtk_widget_destroy(guihistocontrolflow_get_widget(histo_control_flow_data));
+  //histo_control_flow_data->mw = NULL;
+  //FIXME guihistocontrolflow_destructor(histo_control_flow_data);
+}
+
+/* When this destructor is called, the widgets are already disconnected */
+void guihistocontrolflow_destructor(HistoControlFlowData *histo_control_flow_data)
+{
+  Tab *tab = histo_control_flow_data->tab;
+  
+  g_info("HISTOCFV.c : guihistocontrolflow_destructor, %p", histo_control_flow_data);
+  g_info("%p, %p, %p", histo_update_time_window_hook, histo_control_flow_data, tab);
+  if(GTK_IS_WIDGET(guihistocontrolflow_get_widget(histo_control_flow_data)))
+    g_info("widget still exists");
+  
+  /* ButtonWidget is removed with it's widget */
+  //buttonwidget_destroy(histo_control_flow_data->buttonwidget);
+  if(tab != NULL)
+  {
+      // Delete reading hooks
+    lttvwindow_unregister_traceset_notify(tab,
+        histo_traceset_notify,
+        histo_control_flow_data);
+    
+    lttvwindow_unregister_time_window_notify(tab,
+        histo_update_time_window_hook,
+        histo_control_flow_data);
+  
+    lttvwindow_unregister_current_time_notify(tab,
+        histo_update_current_time_hook,
+        histo_control_flow_data);
+
+    lttvwindow_unregister_redraw_notify(tab, histo_redraw_notify, histo_control_flow_data);
+    lttvwindow_unregister_continue_notify(tab,
+                                          histo_continue_notify,
+                                          histo_control_flow_data);
+    
+    lttvwindow_events_request_remove_all(histo_control_flow_data->tab,
+                                         histo_control_flow_data);
+
+    lttvwindow_unregister_filter_notify(tab,
+                        histo_filter_changed, histo_control_flow_data);
+
+  }
+  lttvwindowtraces_background_notify_remove(histo_control_flow_data);
+  g_histo_control_flow_data_list = 
+         g_slist_remove(g_histo_control_flow_data_list,histo_control_flow_data);
+
+  g_array_free(histo_control_flow_data->number_of_process, TRUE);
+
+  g_info("HISTOCFV.c : guihistocontrolflow_destructor end, %p", histo_control_flow_data);
+  g_free(histo_control_flow_data);
+}
+
+
diff --git a/ltt/branches/poly/lttv/modules/gui/histogram/histocfv.h b/ltt/branches/poly/lttv/modules/gui/histogram/histocfv.h
new file mode 100644 (file)
index 0000000..4ab1051
--- /dev/null
@@ -0,0 +1,94 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2006 Parisa heidari (inspired from CFV by 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.
+ */
+
+
+
+#ifndef _HISTOCFV_H
+#define _HISTOCFV_H
+
+#include <gtk/gtk.h>
+#include <lttvwindow/mainwindow.h>
+//#include "histobuttonwidget.h"
+
+extern GQuark LTT_NAME_CPU;
+
+
+#ifndef TYPE_histoDrawing_t_DEFINED
+#define TYPE_histoDrawing_t_DEFINED
+typedef struct _histoDrawing_t histoDrawing_t;
+#endif //TYPE_histoDrawing_t_DEFINED
+
+#ifndef TYPE_ButtonWidget_DEFINED
+#define TYPE_ButtonWidget_DEFINED
+typedef struct _ButtonWidget ButtonWidget;
+#endif //TYPE_ButtonWidget_DEFINED
+
+#ifndef TYPE_HistoControlFlowData_DEFINED
+#define TYPE_HistoControlFlowData_DEFINED
+typedef struct _HistoControlFlowData HistoControlFlowData;
+#endif //TYPE_HistoControlFlowData_DEFINED
+
+
+
+struct _HistoControlFlowData {
+
+  GtkWidget *top_widget;//The hbox containing buttons and drawing area.
+  Tab *tab; 
+  GtkWidget *box;
+  GtkWidget *ev_box;//for histogram
+  ButtonWidget *buttonwidget;
+
+  histoDrawing_t *drawing;
+  //GtkAdjustment *v_adjust ;//may be used later for scrollbar
+
+  /* Shown events information */
+//  TimeWindow time_window;
+//  LttTime current_time;
+  
+  //guint currently_Selected_Event  ;
+  GArray  *number_of_process;//number of events
+  guint background_info_waiting; /* Number of background requests waited for
+                                    in order to have all the info ready. */
+// For histogram  
+  guint max_height;
+
+ LttvFilter *histo_main_win_filter;
+} ;
+
+/* Control Flow Data constructor */
+HistoControlFlowData *guihistocontrolflow(Tab *tab);
+void
+guihistocontrolflow_destructor_full(HistoControlFlowData *histo_control_flow_data);
+void
+guihistocontrolflow_destructor(HistoControlFlowData *histo_control_flow_data);
+
+static inline GtkWidget *guihistocontrolflow_get_widget(
+                         HistoControlFlowData *histo_control_flow_data)
+{
+  return histo_control_flow_data->top_widget ;
+}
+
+static inline ButtonWidget *guihistocontrolflow_get_buttonwidget
+    (HistoControlFlowData *histo_control_flow_data)
+{
+    return histo_control_flow_data->buttonwidget ;
+}
+
+
+
+#endif // _HISTOCFV_H
diff --git a/ltt/branches/poly/lttv/modules/gui/histogram/histodrawing.c b/ltt/branches/poly/lttv/modules/gui/histogram/histodrawing.c
new file mode 100644 (file)
index 0000000..39095ff
--- /dev/null
@@ -0,0 +1,1291 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2006 Parisa heidari (inspired from CFV by 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <string.h>
+
+#include <ltt/trace.h>
+
+#include <lttv/lttv.h>
+#include <lttv/tracecontext.h>
+#include <lttvwindow/lttvwindow.h>
+#include <lttv/state.h>
+#include <lttv/hook.h>
+
+#include "histodrawing.h"
+#include "histoeventhooks.h"
+#include "histocfv.h"
+
+#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
+#define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
+
+//FIXME
+#define TRACE_NUMBER 0
+#define EXTRA_ALLOC 1024 // pixels
+#define padding_width 50
+
+#if 0 /* colors for two lines representation */
+GdkColor histo_drawing_colors[NUM_COLORS] =
+{ /* Pixel, R, G, B */
+  { 0, 0, 0, 0 }, /* COL_BLACK */
+  { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_WHITE */
+  { 0, 0x0FFF, 0xFFFF, 0xFFFF }, /* COL_WAIT_FORK : pale blue */
+  { 0, 0xFFFF, 0xFFFF, 0x0000 }, /* COL_WAIT_CPU : yellow */
+  { 0, 0xFFFF, 0xA000, 0xFCFF }, /* COL_EXIT : pale magenta */
+  { 0, 0xFFFF, 0x0000, 0xFFFF }, /* COL_ZOMBIE : purple */
+  { 0, 0xFFFF, 0x0000, 0x0000 }, /* COL_WAIT : red */
+  { 0, 0x0000, 0xFFFF, 0x0000 }, /* COL_RUN : green */
+  { 0, 0x8800, 0xFFFF, 0x8A00 }, /* COL_USER_MODE : pale green */
+  { 0, 0x09FF, 0x01FF, 0xFFFF }, /* COL_SYSCALL : blue */
+  { 0, 0xF900, 0x4200, 0xFF00 }, /* COL_TRAP : pale purple */
+  { 0, 0xFFFF, 0x5AFF, 0x01FF }, /* COL_IRQ : orange */
+  { 0, 0xFFFF, 0xFFFF, 0xFFFF }  /* COL_MODE_UNKNOWN : white */
+
+};
+#endif //0
+
+
+ GdkColor histo_drawing_colors[NUM_COLORS] =
+{ /* Pixel, R, G, B */
+  { 0, 0, 0, 0 }, /* COL_BLACK */
+  { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_WHITE */
+  { 0, 0x0000, 0xFF00, 0x0000 }, /* COL_RUN_USER_MODE : green */
+  { 0, 0x0100, 0x9E00, 0xFFFF }, /* COL_RUN_SYSCALL : pale blue */
+  { 0, 0xFF00, 0xFF00, 0x0100 }, /* COL_RUN_TRAP : yellow */
+  { 0, 0xFFFF, 0x5E00, 0x0000 }, /* COL_RUN_IRQ : red */
+  { 0, 0x6600, 0x0000, 0x0000 }, /* COL_WAIT : dark red */
+  { 0, 0x7700, 0x7700, 0x0000 }, /* COL_WAIT_CPU : dark yellow */
+  { 0, 0x6400, 0x0000, 0x5D00 }, /* COL_ZOMBIE : dark purple */
+  { 0, 0x0700, 0x6400, 0x0000 }, /* COL_WAIT_FORK : dark green */
+  { 0, 0x8900, 0x0000, 0x8400 }, /* COL_EXIT : "less dark" magenta */
+  { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_MODE_UNKNOWN : white */
+  { 0, 0xFFFF, 0xFFFF, 0xFFFF }  /* COL_UNNAMED : white */
+
+};
+
+/*
+RUN+USER MODE green
+RUN+SYSCALL
+RUN+TRAP
+RUN+IRQ
+WAIT+foncé
+WAIT CPU + WAIT FORK vert foncé ou jaune
+IRQ rouge
+TRAP: orange
+SYSCALL: bleu pâle
+
+ZOMBIE + WAIT EXIT
+*/
+
+
+/*****************************************************************************
+ *                              drawing functions                            *
+ *****************************************************************************/
+
+static gboolean
+histo_expose_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data );
+
+static gboolean
+histo_expose_vertical_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data );
+
+static gboolean
+histo_motion_notify_ruler(GtkWidget *widget, GdkEventMotion *event, gpointer user_data);
+
+static gboolean
+histo_motion_notify_vertical_ruler(GtkWidget *widget, GdkEventMotion *event, gpointer user_data);
+
+/* Function responsible for updating the exposed area.
+ * It must do an events request to the lttvwindow API to ask for this update.
+ * Note : this function cannot clear the background, because it may
+ * erase drawing already present (SAFETY).
+ */
+void histo_drawing_data_request(histoDrawing_t *drawing,
+      gint x, gint y,
+      gint width,
+      gint height)
+{
+
+}
+
+void histo_drawing_data_request_begin(EventsRequest *events_request, LttvTracesetState *tss)
+{
+  g_debug("Begin of data request");
+  HistoControlFlowData *cfd = events_request->viewer_data;
+  LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tss);
+  TimeWindow time_window = 
+    lttvwindow_get_time_window(cfd->tab);
+
+  guint width = cfd->drawing->width;
+  guint x=0;
+
+  cfd->drawing->last_start = events_request->start_time;
+
+  histo_convert_time_to_pixels(
+          time_window,
+          events_request->start_time,
+          width,
+          &x);
+
+ }
+
+ void histo_drawing_chunk_begin(EventsRequest *events_request, LttvTracesetState *tss)
+{
+  g_debug("Begin of chunk");
+  HistoControlFlowData *cfd = events_request->viewer_data;
+  LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tss);
+  //LttTime current_time = lttv_traceset_context_get_current_tfc(tsc)->timestamp;
+  guint num_cpu = 
+    ltt_trace_get_num_cpu(tss->parent.traces[TRACE_NUMBER]->t);
+
+  /* //disabled for histogram
+   cfd->process_list->current_hash_data = g_new(HashedProcessData*,num_cpu);
+  memset(cfd->process_list->current_hash_data, 0,
+         sizeof(HashedProcessData*)*num_cpu);*/
+  //cfd->drawing->last_start = LTT_TIME_MIN(current_time,
+  //                                        events_request->end_time);
+}
+
+
+void histo_drawing_request_expose(EventsRequest *events_request,
+                            LttvTracesetState *tss,
+                            LttTime end_time)
+{
+  HistoControlFlowData *cfd = events_request->viewer_data;
+  histoDrawing_t *drawing = cfd->drawing;
+   
+  gint x, x_end, width;
+  LttvTracesetContext *tsc = (LttvTracesetContext*)tss;
+    
+  TimeWindow time_window = 
+        lttvwindow_get_time_window(cfd->tab);
+
+  g_debug("histo request expose");
+  
+  histo_convert_time_to_pixels(
+        time_window,
+        end_time,
+        drawing->width,
+        &x_end);
+  x = drawing->damage_begin;
+
+  width = x_end - x;
+
+  drawing->damage_begin = x+width;
+
+  // FIXME ?
+  //changed for histogram:
+  gtk_widget_queue_draw_area ( drawing->drawing_area,
+                               x, 0,
+                               width,
+                              drawing->/*drawing_area->allocation.*/height);
+  // Update directly when scrolling 
+  gdk_window_process_updates(drawing->drawing_area->window,
+      TRUE);
+}
+
+
+/* Callbacks */
+
+
+/* Create a new backing pixmap of the appropriate size */
+/* As the scaling will always change, it's of no use to copy old
+ * pixmap.
+ *
+ * Change the size if width or height changes. 
+ * (different from control flow viewer!)
+ */
+static gboolean
+histo_configure_event( GtkWidget *widget, GdkEventConfigure *event, 
+    gpointer user_data)
+{
+  histoDrawing_t *drawing = (histoDrawing_t*)user_data;
+
+  /* First, get the new time interval of the main window */
+  /* we assume (see documentation) that the main window
+   * has updated the time interval before this configure gets
+   * executed.
+   */
+  //lttvwindow_get_time_window(drawing->histo_control_flow_data->mw,
+  //      &drawing->histo_control_flow_data->time_window);
+  
+  /* New pixmap, size of the configure event */
+  //GdkPixmap *pixmap = gdk_pixmap_new(widget->window,
+  //      widget->allocation.width + SAFETY,
+  //      widget->allocation.height + SAFETY,
+  //      -1);
+    g_debug("drawing configure event");
+    g_debug("New alloc draw size : %i by %i",widget->allocation.width,
+                                    widget->allocation.height);
+
+/*modified for histogram, if width is not changed, GArray is valid so
+ just redraw, else recalculate all.(event request again)*/
+
+//enabled again for histogram:
+      if(drawing->pixmap)
+        gdk_pixmap_unref(drawing->pixmap);
+
+      drawing->pixmap = gdk_pixmap_new(widget->window,
+                                       widget->allocation.width ,//+ SAFETY + EXTRA_ALLOC,
+                                       widget->allocation.height + EXTRA_ALLOC,
+                                       -1);
+
+//end add
+      drawing->alloc_width = drawing->width + SAFETY + EXTRA_ALLOC;
+      drawing->alloc_height = drawing->height + EXTRA_ALLOC;
+     
+    //drawing->height = widget->allocation.height;
+
+   
+
+//     Clear the image
+//    gdk_draw_rectangle (drawing->pixmap,
+//          widget->style->black_gc,
+//          TRUE,
+//          0, 0,
+//          drawing->width+SAFETY,
+//          drawing->height);
+
+    //g_info("init data request");
+
+
+    /* Initial data request */
+    /* no, do initial data request in the expose event */
+    // Do not need to ask for data of 1 pixel : not synchronized with
+    // main window time at this moment.
+    //histo_drawing_data_request(drawing, &drawing->pixmap, 0, 0,
+    //    widget->allocation.width,
+    //    widget->allocation.height);
+                          
+    //drawing->width = widget->allocation.width;
+    //drawing->height = widget->allocation.height;
+  
+    drawing->damage_begin = 0;
+    drawing->damage_end = widget->allocation.width;
+    
+    if((widget->allocation.width != 1 &&
+        widget->allocation.height != 1)
+        /*&& drawing->damage_begin < drawing->damage_end */)
+    {
+
+      gdk_draw_rectangle (drawing->pixmap,
+      drawing->drawing_area->style->black_gc,
+      TRUE,
+      0, 0,
+      drawing->drawing_area->allocation.width, drawing->drawing_area->allocation.height);
+ /*     histo_drawing_data_request(drawing,
+                           drawing->damage_begin,
+                           0,
+                           drawing->damage_end - drawing->damage_begin,
+                           drawing->height);*/
+    }
+//modified for histogram
+       
+  if(widget->allocation.width == drawing->width) 
+  {
+    
+    drawing->height = widget->allocation.height;
+    histogram_show( drawing->histo_control_flow_data,0,
+       drawing->histo_control_flow_data->number_of_process->len);
+  }
+  else
+  { 
+    drawing->width = widget->allocation.width;
+    drawing->height = widget->allocation.height;
+
+    g_array_set_size (drawing->histo_control_flow_data->number_of_process,
+                        widget->allocation.width);
+    histo_request_event( drawing->histo_control_flow_data,drawing->damage_begin
+                       ,drawing->damage_end - drawing->damage_begin);
+  }
+  return TRUE;
+}
+
+
+/* Redraw the screen from the backing pixmap */
+static gboolean
+histo_expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
+{
+  histoDrawing_t *drawing = (histoDrawing_t*)user_data;
+
+  HistoControlFlowData *histo_control_flow_data =
+      (HistoControlFlowData*)g_object_get_data(
+                G_OBJECT(widget),
+                "histo_control_flow_data");
+#if 0
+  if(unlikely(drawing->gc == NULL)) {
+    drawing->gc = gdk_gc_new(drawing->drawing_area->window);
+    gdk_gc_copy(drawing->gc, drawing->drawing_area->style->black_gc);
+  }
+#endif //0
+  TimeWindow time_window = 
+      lttvwindow_get_time_window(histo_control_flow_data->tab);
+  LttTime current_time = 
+      lttvwindow_get_current_time(histo_control_flow_data->tab);
+
+  guint cursor_x=0;
+
+  LttTime window_end = time_window.end_time;
+
+
+  /* update the screen from the pixmap buffer */
+//added again for histogram:
+
+  gdk_draw_pixmap(widget->window,
+      widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+      drawing->pixmap,
+      event->area.x, event->area.y,
+      event->area.x, event->area.y,
+      event->area.width, event->area.height);
+ //0
+
+  drawing->height = drawing-> drawing_area ->allocation.height;
+
+#if 0
+  copy_pixmap_to_screen(histo_control_flow_data->process_list,
+                        widget->window,
+                        widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+                        event->area.x, event->area.y,
+                        event->area.width, event->area.height);
+#endif //0
+
+
+ /* //disabled for histogram
+  copy_pixmap_to_screen(histo_control_flow_data->process_list,
+                        widget->window,
+                        drawing->gc,
+                        event->area.x, event->area.y,
+                        event->area.width, event->area.height);*/
+
+  /* Erase the dotted lines left.. */
+  if(widget->allocation.height > drawing->height)
+  {
+    gdk_draw_rectangle (widget->window,
+      drawing->drawing_area->style->black_gc,
+      TRUE,
+      event->area.x, drawing->height,
+      event->area.width,  // do not overlap
+      widget->allocation.height - drawing->height);
+  }
+  if(ltt_time_compare(time_window.start_time, current_time) <= 0 &&
+           ltt_time_compare(window_end, current_time) >= 0)
+  {
+    /* Draw the dotted lines */
+    histo_convert_time_to_pixels(
+          time_window,
+          current_time,
+          drawing->width,
+          &cursor_x);
+
+#if 0
+    if(drawing->dotted_gc == NULL) {
+
+      drawing->dotted_gc = gdk_gc_new(drawing->drawing_area->window);
+      gdk_gc_copy(drawing->dotted_gc, widget->style->white_gc);
+   
+      gint8 dash_list[] = { 1, 2 };
+      gdk_gc_set_line_attributes(drawing->dotted_gc,
+                                 1,
+                                 GDK_LINE_ON_OFF_DASH,
+                                 GDK_CAP_BUTT,
+                                 GDK_JOIN_MITER);
+      gdk_gc_set_dashes(drawing->dotted_gc,
+                        0,
+                        dash_list,
+                        2);
+    }
+#endif //0
+    gint height_tot = MAX(widget->allocation.height, drawing->height);
+    gdk_draw_line(widget->window,
+                  drawing->dotted_gc,
+                  cursor_x, 0,
+                  cursor_x, height_tot);
+  }
+  
+  return FALSE;
+}
+
+static gboolean
+histo_after_expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
+{
+  //g_assert(0);
+  g_debug("AFTER EXPOSE");
+
+  return FALSE;
+}
+
+/* mouse click */
+static gboolean
+histo_button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer user_data )
+{
+  HistoControlFlowData *histo_control_flow_data =
+      (HistoControlFlowData*)g_object_get_data(
+                G_OBJECT(widget),
+                "histo_control_flow_data");
+  histoDrawing_t *drawing = histo_control_flow_data->drawing;
+  TimeWindow time_window =
+               lttvwindow_get_time_window(histo_control_flow_data->tab);
+
+  g_debug("click");
+  if(event->button == 1)
+  {
+    LttTime time;
+
+    /* left mouse button click */
+    g_debug("x click is : %f", event->x);
+
+    histo_convert_pixels_to_time(drawing->width, (guint)event->x,
+        time_window,
+        &time);
+
+    lttvwindow_report_current_time(histo_control_flow_data->tab, time);
+    ////report event->y for vertical zoom +,-
+  }
+
+  return FALSE;
+}
+/*
+ //Viewer's vertical scroll bar is already omitted, not needed for histogram.
+static gboolean
+scrollbar_size_allocate(GtkWidget *widget,
+                        GtkAllocation *allocation,
+                        gpointer user_data)
+{
+  histoDrawing_t *drawing = (histoDrawing_t*)user_data;
+
+  gtk_widget_set_size_request(drawing->padding, allocation->width, -1);
+  //gtk_widget_queue_resize(drawing->padding);
+  //gtk_widget_queue_resize(drawing->ruler);
+  gtk_container_check_resize(GTK_CONTAINER(drawing->ruler_hbox));
+  return 0;
+}
+*/
+
+
+histoDrawing_t *histo_drawing_construct(HistoControlFlowData *histo_control_flow_data)
+{
+  histoDrawing_t *drawing = g_new(histoDrawing_t, 1);
+  
+  drawing->histo_control_flow_data = histo_control_flow_data;
+
+  drawing->vbox = gtk_vbox_new(FALSE, 1);
+
+  
+  drawing->ruler_hbox = gtk_hbox_new(FALSE, 1);
+  drawing->ruler = gtk_drawing_area_new ();
+  //gtk_widget_set_size_request(drawing->ruler, -1, 27);
+  
+  drawing->padding = gtk_drawing_area_new ();
+  //gtk_widget_set_size_request(drawing->padding, -1, 27);
+   
+  gtk_box_pack_start(GTK_BOX(drawing->ruler_hbox), drawing->padding,FALSE, FALSE, 0);
+  
+  gtk_box_pack_end(GTK_BOX(drawing->ruler_hbox), drawing->ruler, 
+                     TRUE, TRUE, 0);
+
+  drawing->drawing_area = gtk_drawing_area_new ();
+  
+  drawing->gc = NULL;
+  /* 
+  ///at this time not necessary for histogram
+  drawing->hbox = gtk_hbox_new(FALSE, 1);
+  drawing->viewport = gtk_viewport_new(NULL, histo_control_flow_data->v_adjust);
+  drawing->scrollbar = gtk_vscrollbar_new(histo_control_flow_data->v_adjust);
+  gtk_box_pack_start(GTK_BOX(drawing->hbox), drawing->viewport, 
+                     TRUE, TRUE, 0);
+  gtk_box_pack_end(GTK_BOX(drawing->hbox), drawing->scrollbar, 
+                     FALSE, FALSE, 0);
+  gtk_container_add(GTK_CONTAINER(drawing->viewport),
+                    drawing->drawing_area);*/
+
+  //add vertical ruler:
+  drawing->vruler_drawing_hbox = gtk_hbox_new(FALSE, 1);
+  drawing-> vertical_ruler =gtk_drawing_area_new ();
+  gtk_box_pack_start(GTK_BOX(drawing->vruler_drawing_hbox), drawing->vertical_ruler, 
+                       FALSE, FALSE, 0);
+  gtk_box_pack_end(GTK_BOX(drawing->vruler_drawing_hbox), drawing->drawing_area,
+                       TRUE, TRUE, 1);
+  gtk_widget_set_size_request(drawing->vertical_ruler, padding_width, -1);
+
+  gtk_box_pack_start(GTK_BOX(drawing->vbox), drawing->ruler_hbox, 
+                       FALSE, FALSE, 1);
+  gtk_box_pack_end(GTK_BOX(drawing->vbox), drawing->vruler_drawing_hbox/*drawing_area*/,
+                       TRUE, TRUE, 1);
+  
+  drawing->pango_layout =
+       gtk_widget_create_pango_layout(drawing->drawing_area, NULL);
+
+  drawing->height = 1;
+  drawing->width = 1;
+  drawing->depth = 0;
+  drawing->alloc_height = 1;
+  drawing->alloc_width = 1;
+  
+  drawing->damage_begin = 0;
+  drawing->damage_end = 0;
+  drawing->horizontal_sel = -1;
+  
+  //gtk_widget_set_size_request(drawing->drawing_area->window, 50, 50);
+  g_object_set_data_full(
+      G_OBJECT(drawing->drawing_area),
+      "histo_Link_drawing_Data",
+      drawing,
+      (GDestroyNotify)histo_drawing_destroy);
+
+  g_object_set_data(
+      G_OBJECT(drawing->ruler),
+      "histo_drawing",
+      drawing);
+
+  g_object_set_data(
+      G_OBJECT(drawing->vertical_ruler),
+      "histo_drawing",
+      drawing);
+
+  //gtk_widget_modify_bg( drawing->drawing_area,
+  //      GTK_STATE_NORMAL,
+  //      &CF_Colors[BLACK]);
+  
+  //gdk_window_get_geometry(drawing->drawing_area->window,
+  //    NULL, NULL,
+  //    &(drawing->width),
+  //    &(drawing->height),
+  //    -1);
+  
+  //drawing->pixmap = gdk_pixmap_new(
+  //    drawing->drawing_area->window,
+  //    drawing->width,
+  //    drawing->height,
+  //    drawing->depth);
+  
+  drawing->pixmap = NULL;
+
+//  drawing->pixmap = gdk_pixmap_new(drawing->drawing_area->window,
+//        drawing->drawing_area->allocation.width,
+//        drawing->drawing_area->allocation.height,
+//        -1);
+
+  g_signal_connect (G_OBJECT(drawing->drawing_area),
+        "configure_event",
+        G_CALLBACK (histo_configure_event),
+        (gpointer)drawing);
+  g_signal_connect (G_OBJECT(drawing->ruler),
+        "expose_event",
+        G_CALLBACK(histo_expose_ruler),
+        (gpointer)drawing);
+
+  gtk_widget_add_events(drawing->ruler, GDK_POINTER_MOTION_MASK);
+  gtk_widget_add_events(drawing->vertical_ruler, GDK_POINTER_MOTION_MASK);
+
+  g_signal_connect (G_OBJECT(drawing->ruler),
+        "motion-notify-event",
+        G_CALLBACK(histo_motion_notify_ruler),
+        (gpointer)drawing);
+
+  g_signal_connect (G_OBJECT(drawing->vertical_ruler),
+        "expose_event",
+        G_CALLBACK(histo_expose_vertical_ruler),
+        (gpointer)drawing);
+
+  g_signal_connect (G_OBJECT(drawing->vertical_ruler),
+        "motion-notify-event",
+        G_CALLBACK(histo_motion_notify_vertical_ruler),
+        (gpointer)drawing);
+
+/*//not necessary for historam. 
+  g_signal_connect (G_OBJECT(drawing->drawing_area),
+        "size-allocate",
+        G_CALLBACK(scrollbar_size_allocate),
+        (gpointer)drawing); */
+
+
+  gtk_widget_set_size_request(drawing->padding, padding_width, -1);//use it for vertical ruler
+
+  g_signal_connect (G_OBJECT(drawing->drawing_area),
+        "expose_event",
+        G_CALLBACK (histo_expose_event),
+        (gpointer)drawing);
+
+  g_signal_connect_after (G_OBJECT(drawing->drawing_area),
+        "expose_event",
+        G_CALLBACK (histo_after_expose_event),
+        (gpointer)drawing);
+
+  g_signal_connect (G_OBJECT(drawing->drawing_area),
+        "button-press-event",
+        G_CALLBACK (histo_button_press_event),
+        (gpointer)drawing);
+  
+  gtk_widget_show(drawing->ruler);
+  gtk_widget_show(drawing->padding);
+  gtk_widget_show(drawing->ruler_hbox);
+  gtk_widget_show(drawing->vertical_ruler);
+  gtk_widget_show(drawing->vruler_drawing_hbox);
+  gtk_widget_show(drawing->drawing_area);
+  
+ /// gtk_widget_show(drawing->viewport);
+ /// gtk_widget_show(drawing->scrollbar);
+ /// gtk_widget_show(drawing->hbox);
+
+  /* Allocate the colors */
+  GdkColormap* colormap = gdk_colormap_get_system();
+  gboolean success[NUM_COLORS];
+  gdk_colormap_alloc_colors(colormap, histo_drawing_colors, NUM_COLORS, FALSE,
+                            TRUE, success);
+  
+  drawing->gc =
+    gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(histo_control_flow_data->tab)->window));
+  drawing->dotted_gc =
+    gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(histo_control_flow_data->tab)->window));
+
+  gdk_gc_copy(drawing->gc,
+      main_window_get_widget(histo_control_flow_data->tab)->style->black_gc);
+  gdk_gc_copy(drawing->dotted_gc,
+      main_window_get_widget(histo_control_flow_data->tab)->style->white_gc);
+  
+  gint8 dash_list[] = { 1, 2 };
+  gdk_gc_set_line_attributes(drawing->dotted_gc,
+                             1,
+                             GDK_LINE_ON_OFF_DASH,
+                             GDK_CAP_BUTT,
+                             GDK_JOIN_MITER);
+  gdk_gc_set_dashes(drawing->dotted_gc,
+                    0,
+                    dash_list,
+                    2);
+
+  drawing->ruler_gc_butt = 
+    gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(histo_control_flow_data->tab)->window));
+  gdk_gc_copy(drawing->ruler_gc_butt, 
+      main_window_get_widget(histo_control_flow_data->tab)->style->black_gc);
+  drawing->ruler_gc_round = 
+    gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(histo_control_flow_data->tab)->window));
+  gdk_gc_copy(drawing->ruler_gc_round, 
+      main_window_get_widget(histo_control_flow_data->tab)->style->black_gc);
+
+
+  gdk_gc_set_line_attributes(drawing->ruler_gc_butt,
+                               2,
+                               GDK_LINE_SOLID,
+                               GDK_CAP_BUTT,
+                               GDK_JOIN_MITER);
+
+  gdk_gc_set_line_attributes(drawing->ruler_gc_round,
+                             2,
+                             GDK_LINE_SOLID,
+                             GDK_CAP_ROUND,
+                             GDK_JOIN_ROUND);
+ return drawing;
+}
+
+void histo_drawing_destroy(histoDrawing_t *drawing)
+{
+  g_info("histo_drawing_destroy %p", drawing);
+
+  /* Free the colors */
+  GdkColormap* colormap = gdk_colormap_get_system();
+
+  gdk_colormap_free_colors(colormap, histo_drawing_colors, NUM_COLORS);
+  
+  // Do not unref here, histoDrawing_t destroyed by it's widget.
+  //g_object_unref( G_OBJECT(drawing->drawing_area));
+  if(drawing->gc != NULL)
+    gdk_gc_unref(drawing->gc);
+  
+  g_free(drawing->pango_layout);
+  if(drawing->dotted_gc != NULL) gdk_gc_unref(drawing->dotted_gc);
+  if(drawing->ruler_gc_butt != NULL) gdk_gc_unref(drawing->ruler_gc_butt);
+  if(drawing->ruler_gc_round != NULL) gdk_gc_unref(drawing->ruler_gc_round);
+
+  //added for histogram
+  if(drawing->pixmap)
+        gdk_pixmap_unref(drawing->pixmap);
+  g_free(drawing);
+  g_info("histo_drawing_destroy end");
+}
+
+ GtkWidget *histo_drawing_get_drawing_area(histoDrawing_t *drawing)
+{
+  return drawing->drawing_area;
+}
+
+ GtkWidget *histo_drawing_get_widget(histoDrawing_t *drawing)
+{
+  return drawing->vbox;
+}
+
+ void histo_drawing_draw_line( histoDrawing_t *drawing,
+      GdkPixmap *pixmap,
+      guint x1, guint y1,
+      guint x2, guint y2,
+      GdkGC *GC)
+{
+  gdk_draw_line (pixmap,
+      GC,
+      x1, y1, x2, y2);
+}
+
+void histo_drawing_clear(histoDrawing_t *drawing,guint clear_from,guint clear_to)
+{ 
+  
+  HistoControlFlowData *cfd = drawing->histo_control_flow_data;
+  guint clear_width = clear_to- clear_from;
+ /* 
+  //disabled for histogram
+  rectangle_pixmap(cfd->process_list,
+      drawing->drawing_area->style->black_gc,
+      TRUE,
+      0, 0,
+      drawing->alloc_width,  // do not overlap
+      -1);*/
+  //instead, this is added for histogram
+
+   histo_rectangle_pixmap (drawing->drawing_area->style->black_gc,
+          TRUE,
+          clear_from/*0*/, 0,
+          clear_width/*drawing->width*/,
+          -1,drawing);
+
+
+   
+/*  gdk_draw_rectangle (drawing->pixmap,
+      drawing->drawing_area->style->black_gc,
+      TRUE,
+      0,0,
+      drawing->drawing_area->allocation.width,drawing->drawing_area->allocation.height );
+   
+  /* ask for the buffer to be redrawn */
+//enabled again for histogram.
+  gtk_widget_queue_draw_area ( drawing->drawing_area,
+                               clear_from, 0,
+                               clear_width, drawing->height);
+  gdk_window_process_updates(drawing->drawing_area->window,TRUE);
+//disabled instead for histogram
+  //gtk_widget_queue_draw ( drawing->drawing_area);
+  return;
+}
+
+#if 0
+/* Insert a square corresponding to a new process in the list */
+/* Applies to whole drawing->width */
+void drawing_insert_square(histoDrawing_t *drawing,
+        guint y,
+        guint height)
+{
+  //GdkRectangle update_rect;
+  gboolean reallocate = FALSE;
+  GdkPixmap *new_pixmap;
+
+  /* Allocate a new pixmap with new height */
+  if(drawing->alloc_height < drawing->height + height) {
+
+    new_pixmap = gdk_pixmap_new(drawing->drawing_area->window,
+                                     drawing->width + SAFETY + EXTRA_ALLOC,
+                                     drawing->height + height + EXTRA_ALLOC,
+                                     -1);
+    drawing->alloc_width = drawing->width + SAFETY + EXTRA_ALLOC;
+    drawing->alloc_height = drawing->height + height + EXTRA_ALLOC;
+    reallocate = TRUE;
+
+    /* Copy the high region */
+    gdk_draw_pixmap (new_pixmap,
+      drawing->drawing_area->style->black_gc,
+      drawing->pixmap,
+      0, 0,
+      0, 0,
+      drawing->width + SAFETY, y);
+
+  } else {
+    new_pixmap = drawing->pixmap;
+  }
+
+  //GdkPixmap *pixmap = gdk_pixmap_new(drawing->drawing_area->window,
+  //      drawing->width + SAFETY,
+  //      drawing->height + height,
+  //      -1);
+  
+  /* add an empty square */
+  gdk_draw_rectangle (new_pixmap,
+    drawing->drawing_area->style->black_gc,
+    TRUE,
+    0, y,
+    drawing->width + SAFETY,  // do not overlap
+    height);
+
+  /* copy the bottom of the region */
+  gdk_draw_pixmap (new_pixmap,
+    drawing->drawing_area->style->black_gc,
+    drawing->pixmap,
+    0, y,
+    0, y + height,
+    drawing->width+SAFETY, drawing->height - y);
+
+
+  if(reallocate && likely(drawing->pixmap)) {
+    gdk_pixmap_unref(drawing->pixmap);
+    drawing->pixmap = new_pixmap;
+  }
+  
+  if(unlikely(drawing->height==1)) drawing->height = height;
+  else drawing->height += height;
+  
+  gtk_widget_set_size_request(drawing->drawing_area,
+                             -1,
+                             drawing->height);
+  gtk_widget_queue_resize_no_redraw(drawing->drawing_area);
+  
+  /* ask for the buffer to be redrawn */
+  gtk_widget_queue_draw_area ( drawing->drawing_area,
+                               0, y,
+                               drawing->width, drawing->height-y);
+}
+
+
+/* Remove a square corresponding to a removed process in the list */
+void drawing_remove_square(histoDrawing_t *drawing,
+        guint y,
+        guint height)
+{
+  GdkPixmap *pixmap;
+
+  if(unlikely((guint)drawing->height == height)) {
+    //pixmap = gdk_pixmap_new(
+    //    drawing->drawing_area->window,
+    //    drawing->width + SAFETY,
+    //    1,
+    //    -1);
+    pixmap = drawing->pixmap;
+    drawing->height=1;
+  } else {
+    /* Allocate a new pixmap with new height */
+     //pixmap = gdk_pixmap_new(
+     //   drawing->drawing_area->window,
+     //   drawing->width + SAFETY,
+     //   drawing->height - height,
+     //   -1);
+     /* Keep the same preallocated pixmap */
+    pixmap = drawing->pixmap;
+   
+    /* Copy the high region */
+    gdk_draw_pixmap (pixmap,
+      drawing->drawing_area->style->black_gc,
+      drawing->pixmap,
+      0, 0,
+      0, 0,
+      drawing->width + SAFETY, y);
+
+    /* Copy up the bottom of the region */
+    gdk_draw_pixmap (pixmap,
+      drawing->drawing_area->style->black_gc,
+      drawing->pixmap,
+      0, y + height,
+      0, y,
+      drawing->width, drawing->height - y - height);
+
+    drawing->height-=height;
+  }
+
+  //if(likely(drawing->pixmap))
+  //  gdk_pixmap_unref(drawing->pixmap);
+
+  //drawing->pixmap = pixmap;
+  
+  gtk_widget_set_size_request(drawing->drawing_area,
+                             -1,
+                             drawing->height);
+  gtk_widget_queue_resize_no_redraw(drawing->drawing_area);
+  /* ask for the buffer to be redrawn */
+  gtk_widget_queue_draw_area ( drawing->drawing_area,
+                               0, y,
+                               drawing->width, MAX(drawing->height-y, 1));
+}
+#endif //0
+
+void histo_drawing_update_ruler(histoDrawing_t *drawing, TimeWindow *time_window)
+{
+  GtkRequisition req;
+  GdkRectangle rect;
+  
+  req.width = drawing->ruler->allocation.width;
+  req.height = drawing->ruler->allocation.height;
+
+  rect.x = 0;
+  rect.y = 0;
+  rect.width = req.width;
+  rect.height = req.height;
+
+  gtk_widget_queue_draw(drawing->ruler);
+  //gtk_widget_draw( drawing->ruler, &rect);
+}
+
+/* Redraw the ruler */
+static gboolean
+histo_expose_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
+{
+  histoDrawing_t *drawing = (histoDrawing_t*)user_data;
+  TimeWindow time_window = lttvwindow_get_time_window(drawing->histo_control_flow_data->tab);
+  gchar text[255];
+  
+  PangoContext *context;
+  PangoLayout *layout;
+  PangoFontDescription *FontDesc;
+  PangoRectangle ink_rect;
+  gint global_width=0;
+  GdkColor foreground = { 0, 0, 0, 0 };
+  GdkColor background = { 0, 0xffff, 0xffff, 0xffff };
+
+  LttTime window_end = time_window.end_time;
+  LttTime half_width =
+    ltt_time_div(time_window.time_width,2.0);
+  LttTime window_middle =
+    ltt_time_add(half_width,
+                 time_window.start_time);
+  g_debug("ruler expose event");
+  gdk_draw_rectangle (drawing->ruler->window,
+          drawing->ruler->style->white_gc,
+          TRUE,
+          event->area.x, event->area.y,
+          event->area.width,
+          event->area.height);
+
+  gdk_draw_line (drawing->ruler->window,
+                  drawing->ruler_gc_butt,
+                  event->area.x, 1,
+                  event->area.x + event->area.width, 1);
+
+
+  snprintf(text, 255, "%lus\n%luns",
+    time_window.start_time.tv_sec,
+    time_window.start_time.tv_nsec);
+
+  layout = gtk_widget_create_pango_layout(drawing->drawing_area, NULL);
+
+  context = pango_layout_get_context(layout);
+  FontDesc = pango_context_get_font_description(context);
+
+  pango_font_description_set_size(FontDesc, 6*PANGO_SCALE);
+  pango_layout_context_changed(layout);
+
+  pango_layout_set_text(layout, text, -1);
+  pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
+  global_width += ink_rect.width;
+
+  gdk_draw_layout_with_colors(drawing->ruler->window,
+      drawing->ruler_gc_butt,
+      0,
+      6,
+      layout, &foreground, &background);
+
+  gdk_draw_line (drawing->ruler->window,
+                   drawing->ruler_gc_round,
+                   1, 1,
+                   1, 7);
+
+
+  snprintf(text, 255, "%lus\n%luns", window_end.tv_sec,
+                                     window_end.tv_nsec);
+
+  pango_layout_set_text(layout, text, -1);
+  pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
+  global_width += ink_rect.width;
+
+  if(global_width <= drawing->ruler->allocation.width)
+  {
+    gdk_draw_layout_with_colors(drawing->ruler->window,
+      drawing->ruler_gc_butt,
+      drawing->ruler->allocation.width - ink_rect.width,
+      6,
+      layout, &foreground, &background);
+
+    gdk_draw_line (drawing->ruler->window,
+                   drawing->ruler_gc_butt,
+                   drawing->ruler->allocation.width-1, 1,
+                   drawing->ruler->allocation.width-1, 7);
+  }
+
+
+  snprintf(text, 255, "%lus\n%luns", window_middle.tv_sec,
+                                     window_middle.tv_nsec);
+
+  pango_layout_set_text(layout, text, -1);
+  pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
+  global_width += ink_rect.width;
+
+  if(global_width <= drawing->ruler->allocation.width)
+  {
+    gdk_draw_layout_with_colors(drawing->ruler->window,
+      drawing->ruler_gc_butt,
+      (drawing->ruler->allocation.width - ink_rect.width)/2,
+      6,
+      layout, &foreground, &background);
+
+    gdk_draw_line (drawing->ruler->window,
+                   drawing->ruler_gc_butt,
+                   drawing->ruler->allocation.width/2, 1,
+                   drawing->ruler->allocation.width/2, 7);
+  }
+
+  g_object_unref(layout);
+   
+  return FALSE;
+}
+
+ void histo_drawing_update_vertical_ruler(histoDrawing_t *drawing)//, TimeWindow *time_window)
+{
+  GtkRequisition req;
+  GdkRectangle rect;
+  
+  req.width = drawing->vertical_ruler->allocation.width;
+  req.height = drawing->vertical_ruler->allocation.height;
+  rect.x = 0;
+  rect.y = 0;
+  rect.width = req.width;
+  rect.height = req.height;
+
+  gtk_widget_queue_draw(drawing->vertical_ruler);
+  //gtk_widget_draw( drawing->ruler, &rect);
+}
+
+/* notify mouse on ruler */
+static gboolean
+histo_motion_notify_ruler(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
+{
+  //g_debug("motion");
+  //eventually follow mouse and show time here
+}
+
+static gboolean
+histo_motion_notify_vertical_ruler(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
+{
+  //g_debug("motion");
+  //eventually follow mouse and show time here
+}
+
+
+
+/* Redraw the vertical ruler */
+static gboolean
+histo_expose_vertical_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
+{
+  histoDrawing_t *drawing = (histoDrawing_t*)user_data;
+  HistoControlFlowData *histo_cfv = drawing->histo_control_flow_data;
+  gchar text[255];
+  
+  PangoContext *context;
+  PangoLayout *layout;
+  PangoFontDescription *FontDesc;
+  PangoRectangle ink_rect;
+  gint global_height=0;
+  GdkColor foreground = { 0, 0, 0, 0 };
+  GdkColor background = { 0, 0xffff, 0xffff, 0xffff };
+  GdkColor red ={ 0, 0xFFFF, 0x1E00, 0x1000 };
+  GdkColor magneta ={ 0, 0x8900, 0x0000, 0x8400 };
+  g_debug("vertical ruler expose event");
+  gdk_draw_rectangle (drawing->vertical_ruler->window,
+          drawing->vertical_ruler->style->white_gc,
+          TRUE,
+          event->area.x, event->area.y,
+          event->area.width,
+          event->area.height);
+
+  gdk_draw_line (drawing->vertical_ruler->window,
+                  drawing->ruler_gc_butt,
+                  padding_width-1/*event->area.width-1*/,event->area.y,
+                  padding_width-1/*event->area.width-1*/,event->area.y + event->area.height);
+
+  snprintf(text, 255, "%.1f", (float)histo_cfv->max_height);
+
+  layout = gtk_widget_create_pango_layout(drawing->drawing_area, NULL);
+
+  context = pango_layout_get_context(layout);
+  FontDesc = pango_context_get_font_description(context);
+
+  pango_font_description_set_size(FontDesc, 6*PANGO_SCALE);
+  pango_layout_context_changed(layout);
+
+  pango_layout_set_text(layout, text, -1);
+  pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
+  global_height += ink_rect.height;
+
+  gdk_draw_layout_with_colors(drawing->vertical_ruler->window,
+      drawing->ruler_gc_butt,
+      1,
+      1,
+      layout, &foreground, &background);
+
+  gdk_draw_line (drawing->vertical_ruler->window,
+                   drawing->ruler_gc_round,
+                   drawing->vertical_ruler-> allocation.width-1, 1,
+                   drawing->vertical_ruler-> allocation.width-7, 1);
+
+
+  snprintf(text, 255, "%lu",0);
+
+  pango_layout_set_text(layout, text, -1);
+  pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
+  global_height += ink_rect.height;
+
+  if(global_height <= drawing->vertical_ruler->allocation.height)
+  {
+    gdk_draw_layout_with_colors(drawing->vertical_ruler->window,
+      drawing->ruler_gc_butt,
+      1,
+      drawing->vertical_ruler->allocation.height - ink_rect.height-2,
+      layout, &foreground, &background);
+
+    gdk_draw_line (drawing->vertical_ruler->window,
+                    drawing->ruler_gc_butt,
+                    drawing->vertical_ruler-> allocation.width-1,
+                   drawing->vertical_ruler->allocation.height-1,
+                    drawing->vertical_ruler-> allocation.width-7,
+                   drawing->vertical_ruler->allocation.height-1);
+  }
+
+
+  snprintf(text, 255, "%.1f",(float) histo_cfv->max_height/2.0);
+
+  pango_layout_set_text(layout, text, -1);
+  pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
+  global_height += ink_rect.height;
+
+  if(global_height <= drawing->vertical_ruler->allocation.height)
+  {
+    gdk_draw_layout_with_colors(drawing->vertical_ruler->window,
+      drawing->ruler_gc_butt,
+      1,
+      (drawing->vertical_ruler->allocation.height - ink_rect.height)/2,
+      layout, &foreground, &background);
+
+    gdk_draw_line (drawing->vertical_ruler->window,
+                   drawing->ruler_gc_butt,
+                   drawing->vertical_ruler-> allocation.width-1,
+                  drawing->vertical_ruler-> allocation.height/2,
+                   drawing->vertical_ruler-> allocation.width-7,
+                  drawing->vertical_ruler->allocation.height/2);
+  }
+
+  //show number of events at current time:
+  LttTime current_time = 
+      lttvwindow_get_current_time(histo_cfv->tab);
+  TimeWindow time_window =
+            lttvwindow_get_time_window(histo_cfv->tab);
+  LttTime time_begin = time_window.start_time;
+  LttTime time_width = time_window.time_width;
+  LttTime time_end = ltt_time_add(time_begin, time_width);
+  if((ltt_time_compare(current_time, time_begin) >= 0)&&
+       (ltt_time_compare(current_time, time_end) <= 0))
+  {
+     guint *events_at_currenttime;
+     guint max_height=histo_cfv ->max_height;
+     guint x;
+     histo_convert_time_to_pixels(
+                    time_window,
+                    current_time,
+                    drawing->width,
+                    &x);
+  //   if(x_test<histo_cfv->number_of_process->len)
+
+     {
+       events_at_currenttime = 
+               &g_array_index(histo_cfv->number_of_process,guint,x);
+
+
+           if((*events_at_currenttime) > max_height)
+           {   
+               snprintf(text, 255, "OverFlow!");
+               pango_layout_set_text(layout, text, -1);
+               pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
+               global_height += ink_rect.height;
+               gdk_draw_layout_with_colors(drawing->vertical_ruler->window,
+                               drawing->ruler_gc_butt,
+                               1,
+                               (drawing->vertical_ruler->allocation.height - ink_rect.height)/5, 
+                               layout, &red, &background);
+           }else
+       //    if((*events_at_currenttime) <= max_height)
+           {
+               snprintf(text, 255, "%.1f",
+                       (float) *events_at_currenttime);
+
+               pango_layout_set_text(layout, text, -1);
+               pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
+               global_height += ink_rect.height;
+
+               if ((*events_at_currenttime) == 0)
+               {
+                       gdk_draw_layout_with_colors(drawing->vertical_ruler->window,
+                               drawing->ruler_gc_butt,
+                               1,
+                               (drawing->vertical_ruler->allocation.height - ink_rect.height)-2, 
+                       layout, &red, &background);
+               }
+               else if ((*events_at_currenttime) == max_height)
+               {
+                       gdk_draw_layout_with_colors(drawing->vertical_ruler->window,
+                               drawing->ruler_gc_butt,
+                               1,
+                               1, 
+                       layout, &red, &background);
+               }
+               /*else if ((*events_at_currenttime) == max_height/2) 
+               {
+                       gdk_draw_layout_with_colors(drawing->vertical_ruler->window,
+                               drawing->ruler_gc_butt,
+                               1,
+                               (drawing->vertical_ruler->allocation.height - ink_rect.height)/2, 
+                       layout, &red, &background);
+               }*/
+               else if ((*events_at_currenttime) > max_height/2) 
+               {
+                       gdk_draw_layout_with_colors(drawing->vertical_ruler->window,
+                               drawing->ruler_gc_butt,
+                               1,
+                               (drawing->vertical_ruler->allocation.height - ink_rect.height)/4, 
+                       layout, &red, &background);
+               }
+               else{
+                       gdk_draw_layout_with_colors(drawing->vertical_ruler->window,
+                               drawing->ruler_gc_butt,
+                               1,
+                               ((drawing->vertical_ruler->allocation.height 
+                                       - ink_rect.height)*3)/4,        
+                               layout, &red, &background);
+               }
+           }
+           
+       }
+   }
+
+  g_object_unref(layout);
+   
+  return FALSE;
+}
+
diff --git a/ltt/branches/poly/lttv/modules/gui/histogram/histodrawing.h b/ltt/branches/poly/lttv/modules/gui/histogram/histodrawing.h
new file mode 100644 (file)
index 0000000..179c92e
--- /dev/null
@@ -0,0 +1,224 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2006 Parisa heidari (inspired from CFV by 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.
+ */
+
+
+#ifndef _HISTODRAWING_H
+#define _HISTODRAWING_H
+
+#include <glib.h>
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+#include <ltt/ltt.h>
+#include <lttv/tracecontext.h>
+#include <lttv/state.h>
+#include <lttvwindow/lttvwindow.h>
+#include "histocfv.h"
+#include "histodrawitem.h"
+
+
+#define SAFETY 50 // safety pixels at right and bottom of pixmap buffer
+
+typedef enum _draw_color {
+                COL_BLACK,
+                COL_WHITE,
+                COL_RUN_USER_MODE,/* green */
+                COL_RUN_SYSCALL,  /* pale blue */
+                COL_RUN_TRAP,     /* yellow */
+                COL_RUN_IRQ,      /* red */
+                COL_WAIT,         /* dark red */
+                COL_WAIT_CPU,     /* dark yellow */
+                COL_ZOMBIE,       /* dark purple */
+                COL_WAIT_FORK,    /* dark green */
+                COL_EXIT,         /* "less dark" magenta */
+                COL_MODE_UNKNOWN, /* white */
+                COL_UNNAMED,      /* white */
+                NUM_COLORS } draw_color; 
+
+extern GdkColor histo_drawing_colors[NUM_COLORS];
+
+/* This part of the viewer does :
+ * Draw horizontal lines, getting graphic context as arg.
+ * Copy region of the screen into another.
+ * Modify the boundaries to reflect a scale change. (resize)
+ * Refresh the physical screen with the pixmap
+ * A helper function is provided here to convert from time to process
+ * identifier to pixels and the contrary (will be useful for mouse selection).
+ * Insert an empty square in the drawing, moving the bottom part.
+ *
+ * Note: The last point is exactly why it would not be so easy to add the
+ * vertical line functionnality as in the original version of LTT. In order
+ * to do so, we should keep all processes in the list for the duration of
+ * all the trace instead of dynamically adding and removing them when we
+ * scroll. Another possibility is to redraw all the visible area when a new
+ * process is added to the list. The second solution seems more appropriate
+ * to me.
+ * 
+ *
+ * The pixmap used has the width of the physical window, but the height
+ * of the shown processes.
+ */
+
+#ifndef TYPE_histoDrawing_t_DEFINED
+#define TYPE_histoDrawing_t_DEFINED
+typedef struct _histoDrawing_t histoDrawing_t;
+#endif //TYPE_DRAWING_T_DEFINED
+
+#ifndef TYPE_HistoControlFlowData_DEFINED
+#define TYPE_HistoControlFlowData_DEFINED
+typedef struct _HistoControlFlowData HistoControlFlowData;
+#endif //TYPE_HistoControlFlowData_DEFINED
+
+struct _histoDrawing_t {
+  GtkWidget *vbox;
+  GtkWidget *drawing_area;
+  /*
+  GtkWidget *hbox;
+  GtkWidget *viewport;
+  GtkWidget *scrollbar;*///at this time,not necessary for histogram
+  
+  GtkWidget *ruler_hbox;
+  GtkWidget *ruler;
+  GtkWidget *padding;
+//vertical ruler
+  GtkWidget *vruler_drawing_hbox;
+  GtkWidget *vertical_ruler;
+
+  GdkPixmap *pixmap;
+  HistoControlFlowData *histo_control_flow_data;
+  
+  PangoLayout *pango_layout;
+
+  gint      height, width, depth;
+  /* height and width of allocated buffer pixmap */
+  gint      alloc_height, alloc_width;
+  
+  /* X coordinate of damaged region */
+  gint      damage_begin, damage_end; /* damaged region to be exposed,
+                                         updated per chunk */
+  LttTime   last_start;               
+  GdkGC     *dotted_gc;
+  GdkGC     *gc;
+  GdkGC     *ruler_gc_butt;
+  GdkGC     *ruler_gc_round;
+
+  /* Position of the horizontal selector, -1 for none */
+  gint horizontal_sel;
+};
+
+histoDrawing_t *histo_drawing_construct(HistoControlFlowData *histo_control_flow_data);
+void histo_drawing_destroy(histoDrawing_t *drawing);
+
+
+void histo_drawing_data_request(histoDrawing_t *drawing,
+      gint x, gint y,
+      gint width,
+      gint height);
+
+ GtkWidget *histo_drawing_get_widget(histoDrawing_t *drawing);
+GtkWidget *histo_drawing_get_drawing_area(histoDrawing_t *drawing);
+
+ void histo_drawing_draw_line(histoDrawing_t *drawing,
+      GdkPixmap *pixmap,
+      guint x1, guint y1,
+      guint x2, guint y2,
+      GdkGC *GC);
+
+//void drawing_copy(histoDrawing_t *drawing,
+//    guint xsrc, guint ysrc,
+//    guint xdest, guint ydest,
+//    guint width, guint height);
+
+/* Clear the drawing : make it 1xwidth. */
+void histo_drawing_clear(histoDrawing_t *drawing,guint clear_from,guint clear_to);
+
+/* Insert a square corresponding to a new process in the list */
+static void drawing_insert_square(histoDrawing_t *drawing,
+        guint y,
+        guint height);
+
+/* Remove a square corresponding to a removed process in the list */
+static void drawing_remove_square(histoDrawing_t *drawing,
+        guint y,
+        guint height);
+
+void histo_drawing_update_ruler(histoDrawing_t *drawing, TimeWindow *time_window);
+
+void histo_drawing_update_vertical_ruler(histoDrawing_t *drawing);//, TimeWindow *time_window);
+
+void histo_drawing_request_expose(EventsRequest *events_request,
+                            LttvTracesetState *tss,
+                            LttTime end_time);
+
+void histo_drawing_data_request_begin(EventsRequest *events_request,
+                                LttvTracesetState *tss);
+void histo_drawing_chunk_begin(EventsRequest *events_request, LttvTracesetState *tss);
+
+
+
+static void
+tree_row_activated(GtkTreeModel *treemodel,
+                   GtkTreePath *arg1,
+                   GtkTreeViewColumn *arg2,
+                   gpointer user_data);
+
+
+/* histo_convert_pixels_to_time
+ *
+ * Convert from window pixel and time interval to an absolute time.
+ */
+static inline void histo_convert_pixels_to_time(
+    gint width,
+    guint x,
+    TimeWindow time_window,
+    LttTime *time)
+{
+  double time_d;
+  
+  time_d = time_window.time_width_double;
+  time_d = time_d / (double)width * (double)x;
+  *time = ltt_time_from_double(time_d);
+  *time = ltt_time_add(time_window.start_time, *time);
+}
+
+
+static inline void histo_convert_time_to_pixels(
+    TimeWindow time_window,
+    LttTime time,
+    int width,
+    guint *x)
+{
+  double time_d;
+#ifdef EXTRA_CHECK 
+  g_assert(ltt_time_compare(window_time_begin, time) <= 0 &&
+           ltt_time_compare(window_time_end, time) >= 0);
+#endif //EXTRA_CHECK
+  
+  time = ltt_time_sub(time, time_window.start_time);
+  
+  time_d = ltt_time_to_double(time);
+  
+  if(time_window.time_width_double == 0.0) {
+    g_assert(time_d == 0.0);
+    *x = 0;
+  } else {
+    *x = (guint)(time_d / time_window.time_width_double * (double)width);
+  }
+  
+}
+
+#endif // _DRAWING_H
diff --git a/ltt/branches/poly/lttv/modules/gui/histogram/histodrawitem.c b/ltt/branches/poly/lttv/modules/gui/histogram/histodrawitem.c
new file mode 100644 (file)
index 0000000..aafa515
--- /dev/null
@@ -0,0 +1,464 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 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.
+ */
+
+
+
+/******************************************************************************
+ * drawitem.c
+ *
+ * This file contains methods responsible for drawing a generic type of data
+ * in a drawable. Doing this generically will permit user defined drawing
+ * behavior in a later time.
+ *
+ * This file provides an API which is meant to be reusable for all viewers that
+ * need to show information in line, icon, text, background or point form in
+ * a drawable area having time for x axis. The y axis, in the control flow
+ * viewer case, is corresponding to the different processes, but it can be
+ * reused integrally for cpu, and eventually locks, buffers, network
+ * interfaces... What will differ between the viewers is the precise
+ * information which interests us. We may think that the most useful
+ * information for control flow are some specific events, like schedule
+ * change, and processes'states. It may differ for a cpu viewer : the
+ * interesting information could be more the execution mode of each cpu.
+ * This API in meant to make viewer's writers life easier : it will become
+ * a simple choice of icons and line types for the precise information
+ * the viewer has to provide (agremented with keeping supplementary records
+ * and modifying slightly the DrawContext to suit the needs.)
+ *
+ * We keep each data type in attributes, keys to specific information
+ * being formed from the GQuark corresponding to the information received.
+ * (facilities / facility_name / events / eventname.)
+ * (cpus/cpu_name, process_states/ps_name,
+ * execution_modes/em_name, execution_submodes/es_name).
+ * The goal is then to provide a generic way to print information on the
+ * screen for all this different information.
+ *
+ * Information can be printed as
+ *
+ * - text (text + color + size + position (over or under line)
+ * - icon (icon filename, corresponding to a loaded icon, accessible through
+ *   a GQuark. Icons are loaded statically at the guiControlFlow level during
+ *   module initialization and can be added on the fly if not present in the
+ *   GQuark.) The habitual place for xpm icons is in
+ *   ${prefix}/share/LinuxTraceToolkit.) + position (over or under line)
+ * - line (color, width, style)
+ * - Arc (big points) (color, size)
+ * - background color (color)
+ *
+ * An item is a leaf of the attributes tree. It is, in that case, including
+ * all kind of events categories we can have. It then associates each category
+ * with one or more actions (drawing something) or nothing.
+ * 
+ * Each item has an array of hooks (hook list). Each hook represents an
+ * operation to perform. We seek the array each time we want to
+ * draw an item. We execute each operation in order. An operation type
+ * is associated with each hook to permit user listing and modification
+ * of these operations. The operation type is also used to find the
+ * corresponding priority for the sorting. Operation type and priorities
+ * are enum and a static int table.
+ *
+ * The array has to be sorted by priority each time we add a task in it.
+ * A priority is associated with each operation type. It permits
+ * to perform background color selection before line or text drawing. We also
+ * draw lines before text, so the text appears over the lines.
+ *
+ * Executing all the arrays of operations for a specific event (which
+ * implies information for state, event, cpu, execution mode and submode)
+ * has to be done in a same DrawContext. The goal there is to keep the offset
+ * of the text and icons over and under the middle line, so a specific
+ * event could be printed as (  R Si 0 for running, scheduled in, cpu 0  ),
+ * text being easy to replace with icons. The DrawContext is passed as
+ * call_data for the operation hooks.
+ *
+ * We use the lttv global attributes to keep track of the loaded icons.
+ * If we need an icon, we look for it in the icons / icon name pathname.
+ * If found, we use the pointer to it. If not, we load the pixmap in
+ * memory and set the pointer to the GdkPixmap in the attributes. The
+ * structure pointed to contains the pixmap and the mask bitmap.
+ * 
+ * Author : Mathieu Desnoyers, October 2003
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <lttv/hook.h>
+#include <lttv/attribute.h>
+#include <lttv/iattribute.h>
+#include <string.h>
+
+#include <lttv/tracecontext.h>
+#include <lttv/state.h>
+#include <lttv/lttv.h>
+
+#include "histodrawitem.h"
+
+
+#define MAX_PATH_LEN 256
+
+/* drawing hook functions */
+gboolean histo_draw_text( void *hook_data, void *call_data)
+{
+  histo_PropertiesText *properties = (histo_PropertiesText*)hook_data;
+  histo_DrawContext *draw_context = (histo_DrawContext*)call_data;
+
+  PangoContext *context;
+  PangoLayout *layout;
+  PangoFontDescription *font_desc;// = pango_font_description_new();
+  PangoRectangle ink_rect;
+    
+  layout = draw_context->pango_layout;
+
+  context = pango_layout_get_context(layout);
+  font_desc = pango_context_get_font_description(context);
+
+  pango_font_description_set_size(font_desc, properties->size*PANGO_SCALE);
+  pango_layout_context_changed(layout);
+
+  pango_layout_set_text(layout, properties->text, -1);
+  pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
+
+  gint x=0, y=0;
+  gint *offset=NULL;
+  gboolean enough_space = FALSE;
+  gint width = ink_rect.width;
+
+  switch(properties->histo_position.x) {
+    case POS_START:
+      x = draw_context->histo_drawinfo.start.x;
+      switch(properties->histo_position.y) {
+        case OVER:
+          offset = &draw_context->histo_drawinfo.start.offset.over;
+          x += draw_context->histo_drawinfo.start.offset.over;
+          y = draw_context->histo_drawinfo.y.over;
+          break;
+        case MIDDLE:
+          offset = &draw_context->histo_drawinfo.start.offset.middle;
+          x += draw_context->histo_drawinfo.start.offset.middle;
+          y = draw_context->histo_drawinfo.y.middle;
+          break;
+        case UNDER:
+          offset = &draw_context->histo_drawinfo.start.offset.under;
+          x += draw_context->histo_drawinfo.start.offset.under;
+          y = draw_context->histo_drawinfo.y.under;
+          break;
+      }
+      /* verify if there is enough space to draw */
+      if(unlikely(x + width <= draw_context->histo_drawinfo.end.x)) {
+        enough_space = TRUE;
+        *offset += width;
+      }
+      break;
+    case POS_END:
+      x = draw_context->histo_drawinfo.end.x;
+      switch(properties->histo_position.y) {
+        case OVER:
+          offset = &draw_context->histo_drawinfo.end.offset.over;
+          x += draw_context->histo_drawinfo.end.offset.over;
+          y = draw_context->histo_drawinfo.y.over;
+          break;
+        case MIDDLE:
+          offset = &draw_context->histo_drawinfo.end.offset.middle;
+          x += draw_context->histo_drawinfo.end.offset.middle;
+          y = draw_context->histo_drawinfo.y.middle;
+          break;
+        case UNDER:
+          offset = &draw_context->histo_drawinfo.end.offset.under;
+          x += draw_context->histo_drawinfo.end.offset.under;
+          y = draw_context->histo_drawinfo.y.under;
+          break;
+      }
+      /* verify if there is enough space to draw */
+      if(unlikely(x - width >= draw_context->histo_drawinfo.start.x)) {
+        enough_space = TRUE;
+        *offset -= width;
+      }
+      break;
+  }
+
+  if(unlikely(enough_space))
+    gdk_draw_layout_with_colors(draw_context->drawable,
+              draw_context->gc,
+              x,
+              y,
+              layout, properties->foreground, properties->background);
+
+  return 0;
+}
+
+
+/* To speed up the process, search in already loaded icons list first. Only
+ * load it if not present.
+ */
+gboolean histo_draw_icon( void *hook_data, void *call_data)
+{
+  histo_PropertiesIcon *properties = (histo_PropertiesIcon*)hook_data;
+  histo_DrawContext *draw_context = (histo_DrawContext*)call_data;
+
+  LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
+  LttvAttributeValue value;
+  gchar icon_name[MAX_PATH_LEN] = "icons/";
+  histo_IconStruct *icon_info;
+
+  strcat(icon_name, properties->icon_name);
+  
+  g_assert(lttv_iattribute_find_by_path(attributes, icon_name,
+      LTTV_POINTER, &value));
+  if(unlikely(*(value.v_pointer) == NULL))
+  {
+    *(value.v_pointer) = icon_info = g_new(histo_IconStruct,1);
+    
+    icon_info->pixmap = gdk_pixmap_create_from_xpm(draw_context->drawable,
+                          &icon_info->mask, NULL, properties->icon_name);
+  }
+  else
+  {
+    icon_info = *(value.v_pointer);
+  }
+  
+  gint x=0, y=0;
+  gint *offset=NULL;
+  gboolean enough_space = FALSE;
+  gint width = properties->width;
+  
+  switch(properties->histo_position.x) {
+    case POS_START:
+      x = draw_context->histo_drawinfo.start.x;
+      switch(properties->histo_position.y) {
+        case OVER:
+          offset = &draw_context->histo_drawinfo.start.offset.over;
+          x += draw_context->histo_drawinfo.start.offset.over;
+          y = draw_context->histo_drawinfo.y.over;
+          break;
+        case MIDDLE:
+          offset = &draw_context->histo_drawinfo.start.offset.middle;
+          x += draw_context->histo_drawinfo.start.offset.middle;
+          y = draw_context->histo_drawinfo.y.middle;
+          break;
+        case UNDER:
+          offset = &draw_context->histo_drawinfo.start.offset.under;
+          x += draw_context->histo_drawinfo.start.offset.under;
+          y = draw_context->histo_drawinfo.y.under;
+          break;
+      }
+      /* verify if there is enough space to draw */
+      if(unlikely(x + width <= draw_context->histo_drawinfo.end.x)) {
+        enough_space = TRUE;
+        *offset += width;
+      }
+      break;
+    case POS_END:
+      x = draw_context->histo_drawinfo.end.x;
+      switch(properties->histo_position.y) {
+        case OVER:
+          offset = &draw_context->histo_drawinfo.end.offset.over;
+          x += draw_context->histo_drawinfo.end.offset.over;
+          y = draw_context->histo_drawinfo.y.over;
+          break;
+        case MIDDLE:
+          offset = &draw_context->histo_drawinfo.end.offset.middle;
+          x += draw_context->histo_drawinfo.end.offset.middle;
+          y = draw_context->histo_drawinfo.y.middle;
+          break;
+        case UNDER:
+          offset = &draw_context->histo_drawinfo.end.offset.under;
+          x += draw_context->histo_drawinfo.end.offset.under;
+          y = draw_context->histo_drawinfo.y.under;
+          break;
+      }
+      /* verify if there is enough space to draw */
+      if(unlikely(x - width >= draw_context->histo_drawinfo.start.x)) {
+        enough_space = TRUE;
+        *offset -= width;
+      }
+      break;
+  }
+
+  if(unlikely(enough_space)) {
+    gdk_gc_set_clip_mask(draw_context->gc, icon_info->mask);
+
+    gdk_gc_set_clip_origin(
+        draw_context->gc,
+        x,
+        y);
+    gdk_draw_drawable(draw_context->drawable, 
+        draw_context->gc,
+        icon_info->pixmap,
+        0, 0,
+        x,
+        y,
+        properties->width, properties->height);
+
+    gdk_gc_set_clip_origin(draw_context->gc, 0, 0);
+    gdk_gc_set_clip_mask(draw_context->gc, NULL);
+  }
+  return 0;
+}
+
+gboolean histo_draw_line( void *hook_data, void *call_data)
+{
+  histo_PropertiesLine *properties = (histo_PropertiesLine*)hook_data;
+  histo_DrawContext *draw_context = (histo_DrawContext*)call_data;
+  
+  gdk_gc_set_foreground(draw_context->gc, &properties->color);
+  //gdk_gc_set_rgb_fg_color(draw_context->gc, &properties->color);
+  gdk_gc_set_line_attributes( draw_context->gc,
+                              properties->line_width,
+                              properties->style,
+                              GDK_CAP_BUTT,
+                              GDK_JOIN_MITER);
+  //g_critical("DRAWING LINE : x1: %i, y1: %i, x2:%i, y2:%i", 
+  //    draw_context->previous->middle->x,
+  //    draw_context->previous->middle->y,
+  //    draw_context->drawinfo.middle.x,
+  //    draw_context->drawinfo.middle.y);
+
+  gint x_begin=0, x_end=0, y=0;
+  
+  x_begin = draw_context->histo_drawinfo.start.x;
+  x_end = draw_context->histo_drawinfo.end.x;
+
+  switch(properties->y) {
+    case OVER:
+      y = draw_context->histo_drawinfo.y.over;
+      break;
+    case MIDDLE:
+      y = draw_context->histo_drawinfo.y.middle;
+      break;
+    case UNDER:
+      y = draw_context->histo_drawinfo.y.under;
+      break;
+  }
+
+  histo_drawing_draw_line(
+    NULL, draw_context->drawable,
+    x_begin,
+    y,
+    x_end,
+    y,
+    draw_context->gc);
+  
+  return 0;
+}
+
+gboolean histo_draw_arc( void *hook_data, void *call_data)
+{
+  histo_PropertiesArc *properties = (histo_PropertiesArc*)hook_data;
+  histo_DrawContext *draw_context = (histo_DrawContext*)call_data;
+
+  gdk_gc_set_foreground(draw_context->gc, properties->color);
+  //gdk_gc_set_rgb_fg_color(draw_context->gc, properties->color);
+
+  gint x=0, y=0;
+  gint *offset=NULL;
+  gboolean enough_space = FALSE;
+  gint width = properties->size;
+  
+  switch(properties->histo_position.x) {
+    case POS_START:
+      x = draw_context->histo_drawinfo.start.x;
+      switch(properties->histo_position.y) {
+        case OVER:
+          offset = &draw_context->histo_drawinfo.start.offset.over;
+          x += draw_context->histo_drawinfo.start.offset.over;
+          y = draw_context->histo_drawinfo.y.over;
+          break;
+        case MIDDLE:
+          offset = &draw_context->histo_drawinfo.start.offset.middle;
+          x += draw_context->histo_drawinfo.start.offset.middle;
+          y = draw_context->histo_drawinfo.y.middle;
+          break;
+        case UNDER:
+          offset = &draw_context->histo_drawinfo.start.offset.under;
+          x += draw_context->histo_drawinfo.start.offset.under;
+          y = draw_context->histo_drawinfo.y.under;
+          break;
+      }
+      /* verify if there is enough space to draw */
+      if(unlikely(x + width <= draw_context->histo_drawinfo.end.x)) {
+        enough_space = TRUE;
+        *offset += width;
+      }
+      break;
+    case POS_END:
+      x = draw_context->histo_drawinfo.end.x;
+      switch(properties->histo_position.y) {
+        case OVER:
+          offset = &draw_context->histo_drawinfo.end.offset.over;
+          x += draw_context->histo_drawinfo.end.offset.over;
+          y = draw_context->histo_drawinfo.y.over;
+          break;
+        case MIDDLE:
+          offset = &draw_context->histo_drawinfo.end.offset.middle;
+          x += draw_context->histo_drawinfo.end.offset.middle;
+          y = draw_context->histo_drawinfo.y.middle;
+          break;
+        case UNDER:
+          offset = &draw_context->histo_drawinfo.end.offset.under;
+          x += draw_context->histo_drawinfo.end.offset.under;
+          y = draw_context->histo_drawinfo.y.under;
+          break;
+      }
+      /* verify if there is enough space to draw */
+      if(unlikely(x - width >= draw_context->histo_drawinfo.start.x)) {
+        enough_space = TRUE;
+        *offset -= width;
+      }
+      break;
+  }
+
+  if(unlikely(enough_space))
+    gdk_draw_arc(draw_context->drawable, draw_context->gc,
+          properties->filled,
+          x,
+          y,
+          properties->size, properties->size, 0, 360*64);
+  
+  return 0;
+}
+
+gboolean histo_draw_bg( void *hook_data, void *call_data)
+{
+  histo_PropertiesBG *properties = (histo_PropertiesBG*)hook_data;
+  histo_DrawContext *draw_context = (histo_DrawContext*)call_data;
+
+  gdk_gc_set_foreground(draw_context->gc, properties->color);
+  //gdk_gc_set_rgb_fg_color(draw_context->gc, properties->color);
+
+  //g_critical("DRAWING RECT : x: %i, y: %i, w:%i, h:%i, val1 :%i, val2:%i ", 
+  //    draw_context->previous->over->x,
+  //    draw_context->previous->over->y,
+  //    draw_context->drawinfo.over.x - draw_context->previous->over->x,
+  //    draw_context->previous->under->y-draw_context->previous->over->y,
+  //    draw_context->drawinfo.over.x,
+  //    draw_context->previous->over->x);
+  gdk_draw_rectangle(draw_context->drawable, draw_context->gc,
+          TRUE,
+          draw_context->histo_drawinfo.start.x,
+          draw_context->histo_drawinfo.y.over,
+          draw_context->histo_drawinfo.end.x - draw_context->histo_drawinfo.start.x,
+          draw_context->histo_drawinfo.y.under - draw_context->histo_drawinfo.y.over);
+
+  return 0;
+}
+
+
diff --git a/ltt/branches/poly/lttv/modules/gui/histogram/histodrawitem.h b/ltt/branches/poly/lttv/modules/gui/histogram/histodrawitem.h
new file mode 100644 (file)
index 0000000..909185a
--- /dev/null
@@ -0,0 +1,279 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 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.
+ */
+
+
+#ifndef _DRAW_ITEM_H
+#define _DRAW_ITEM_H
+
+#include <lttv/state.h>
+
+typedef struct _histo_DrawContext histo_DrawContext;
+typedef struct _histo_DrawInfo histo_DrawInfo;
+typedef struct _histo_ItemInfo histo_ItemInfo;
+
+typedef struct _histo_IconStruct histo_IconStruct;
+
+typedef struct _histo_DrawOperation histo_DrawOperation;
+
+
+typedef struct _histo_PropertiesText histo_PropertiesText;
+typedef struct _histo_PropertiesIcon histo_PropertiesIcon;
+typedef struct _histo_PropertiesLine histo_PropertiesLine;
+typedef struct _histo_PropertiesArc histo_PropertiesArc;
+typedef struct _histo_PropertiesBG histo_PropertiesBG;
+
+typedef enum _histo_DrawableItems histo_DrawableItems;
+enum _histo_DrawableItems {
+    ITEM_TEXT, ITEM_ICON, ITEM_LINE, ITEM_POINT, ITEM_BACKGROUND
+};
+
+typedef enum _histo_RelPosX {
+  POS_START, POS_END
+} histo_RelPosX;
+
+typedef enum _histo_RelPosY {
+  OVER, MIDDLE, UNDER
+} histo_RelPosY;
+
+
+/* The DrawContext keeps information about the current drawing position and
+ * the previous one, so we can use both to draw lines.
+ *
+ * over : position for drawing over the middle line.
+ * middle : middle line position.
+ * under : position for drawing under the middle line.
+ *
+ * the modify_* are used to take into account that we should go forward
+ * when we draw a text, an arc or an icon, while it's unneeded when we
+ * draw a line or background.
+ *
+ * The modify_* positions are altered by the draw item functions.
+ *
+ */
+
+
+struct _histo_DrawContext {
+  GdkDrawable *drawable;
+  GdkGC   *gc;
+  PangoLayout *pango_layout;
+
+  struct {
+    struct {
+      gint x;
+      struct {
+        gint over;
+        gint middle;
+        gint under;
+      } offset;
+    } start;
+
+    struct {
+      gint x;
+      struct {
+        gint over;
+        gint middle;
+        gint under;
+      } offset;
+    } end;
+
+    struct {
+      gint over;
+      gint middle;
+      gint under;
+    } y;
+
+  } histo_drawinfo;
+};
+
+
+
+
+/*
+ * Structure used to keep information about icons.
+ */
+struct _histo_IconStruct {
+  GdkPixmap *pixmap;
+  GdkBitmap *mask;
+};
+
+
+/*
+ * The Item element is only used so the DrawOperation is modifiable by users.
+ * During drawing, only the Hook is needed.
+ */
+struct _histo_DrawOperation {
+  histo_DrawableItems item;
+  LttvHooks *hook;
+};
+#if 0
+/*
+ * We define here each items that can be drawn, together with their
+ * associated priority. Many item types can have the same priority,
+ * it's only used for quicksorting the operations when we add a new one
+ * to the array of operations to perform. Lower priorities are executed
+ * first. So, for example, we may want to give background color a value
+ * of 10 while a line would have 20, so the background color, which
+ * is in fact a rectangle, does not hide the line.
+ */
+
+static int Items_Priorities[] = {
+  50, /* ITEM_TEXT */
+  40, /* ITEM_ICON */
+  20, /* ITEM_LINE */
+  30, /* ITEM_POINT */
+  10  /* ITEM_BACKGROUND */
+};
+#endif //0
+
+/*
+ * Here are the different structures describing each item type that can be
+ * drawn. They contain the information necessary to draw the item : not the
+ * position (this is provided by the DrawContext), but the text, icon name,
+ * line width, color; all the properties of the specific items.
+ */
+
+struct _histo_PropertiesText {
+  GdkColor  *foreground;
+  GdkColor  *background;
+  gint       size;
+  gchar     *text;
+  struct {
+    histo_RelPosX    x;
+    histo_RelPosY    y;
+  } histo_position;
+};
+
+
+struct _histo_PropertiesIcon {
+  gchar   *icon_name;
+  gint    width;
+  gint    height;
+  struct {
+    histo_RelPosX    x;
+    histo_RelPosY    y;
+  } histo_position;
+};
+
+struct _histo_PropertiesLine {
+  GdkColor  color;
+  gint    line_width;
+  GdkLineStyle  style;
+  histo_RelPosY    y;
+};
+
+struct _histo_PropertiesArc {
+  GdkColor  *color;
+  gint    size; /* We force circle by width = height */
+  gboolean  filled;
+  struct {
+    histo_RelPosX    x;
+    histo_RelPosY    y;
+  } histo_position;
+};
+
+struct _histo_PropertiesBG {
+  GdkColor  *color;
+};
+
+
+
+void histo_draw_item( GdkDrawable *drawable,
+    gint x,
+    gint y,
+    LttvTraceState *ts,
+    LttvTracefileState *tfs,
+    LttvIAttribute *attributes);
+
+/*
+ * The tree of attributes used to store drawing operations goes like this :
+ *
+ * event_types/
+ *   "facility-event_type"
+ * cpus/
+ *   "cpu name"
+ * mode_types/
+ *   "execution mode"/
+ *     submodes/
+ *       "submode"
+ * process_states/
+ *   "state name"
+ * 
+ * So if, for example, we want to add a hook to get called each time we
+ * receive an event that is in state LTTV_STATE_SYSCALL, we put the
+ * pointer to the GArray of DrawOperation in
+ * process_states/ "name associated with LTTV_STATE_SYSCALL"
+ */
+
+
+#if 0
+/* 
+ * The add_operation has to do a quick sort by priority to keep the operations
+ * in the right order.
+ */
+void add_operation( LttvIAttribute *attributes,
+      gchar *pathname,
+      DrawOperation *operation);
+
+/* 
+ * The del_operation seeks the array present at pathname (if any) and
+ * removes the DrawOperation if present. It returns 0 on success, -1
+ * if it fails.
+ */
+gint del_operation( LttvIAttribute *attributes,
+      gchar *pathname,
+      DrawOperation *operation);
+
+/* 
+ * The clean_operations removes all operations present at a pathname.
+ * returns 0 on success, -1 if it fails.
+ */
+gint clean_operations(  LttvIAttribute *attributes,
+      gchar *pathname );
+
+
+/* 
+ * The list_operations gives a pointer to the operation array associated
+ * with the pathname. It will be NULL if no operation is present.
+ */
+void list_operations( LttvIAttribute *attributes,
+      gchar *pathname,
+      GArray **operation);
+
+
+
+/*
+ * exec_operation executes the operations if present in the attributes, or
+ * do nothing if not present.
+ */
+void exec_operations( LttvIAttribute *attributes,
+      gchar *pathname);
+#endif //0
+
+/*
+ * Here follow the prototypes of the hook functions used to draw the
+ * different items.
+ */
+
+gboolean histo_draw_text( void *hook_data, void *call_data);
+gboolean histo_draw_icon( void *hook_data, void *call_data);
+gboolean histo_draw_line( void *hook_data, void *call_data);
+gboolean histo_draw_arc( void *hook_data, void *call_data);
+gboolean histo_draw_bg( void *hook_data, void *call_data);
+
+
+#endif // _DRAW_ITEM_H
diff --git a/ltt/branches/poly/lttv/modules/gui/histogram/histoeventhooks.c b/ltt/branches/poly/lttv/modules/gui/histogram/histoeventhooks.c
new file mode 100644 (file)
index 0000000..900154b
--- /dev/null
@@ -0,0 +1,1135 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2006 Parisa heidari (inspired from CFV by 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.
+ */
+
+
+/*****************************************************************************
+ *                       Hooks to be called by the main window               *
+ *****************************************************************************/
+
+
+/* Event hooks are the drawing hooks called during traceset read. They draw the
+ * icons, text, lines and background color corresponding to the events read.
+ *
+ * Two hooks are used for drawing : before_schedchange and after_schedchange hooks. The
+ * before_schedchange is called before the state update that occurs with an event and
+ * the after_schedchange hook is called after this state update.
+ *
+ * The before_schedchange hooks fulfill the task of drawing the visible objects that
+ * corresponds to the data accumulated by the after_schedchange hook.
+ *
+ * The after_schedchange hook accumulates the data that need to be shown on the screen
+ * (items) into a queue. Then, the next before_schedchange hook will draw what that
+ * queue contains. That's the Right Way (TM) of drawing items on the screen,
+ * because we need to draw the background first (and then add icons, text, ...
+ * over it), but we only know the length of a background region once the state
+ * corresponding to it is over, which happens to be at the next before_schedchange
+ * hook.
+ *
+ * We also have a hook called at the end of a chunk to draw the information left
+ * undrawn in each process queue. We use the current time as end of
+ * line/background.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+//#define PANGO_ENABLE_BACKEND
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <glib.h>
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+
+//#include <pango/pango.h>
+
+#include <ltt/event.h>
+#include <ltt/time.h>
+#include <ltt/type.h>
+#include <ltt/trace.h>
+
+#include <lttv/lttv.h>
+#include <lttv/hook.h>
+#include <lttv/state.h>
+#include <lttvwindow/lttvwindow.h>
+#include <lttvwindow/lttvwindowtraces.h>
+#include <lttvwindow/support.h>
+
+
+#include "histoeventhooks.h"
+#include "histocfv.h"
+#include "histobuttonwidget.h"
+#include "histodrawing.h"
+
+
+#define MAX_PATH_LEN 256
+#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
+//FIXME
+#define TRACE_NUMBER 0
+#define EXTRA_ALLOC 1024 // pixels
+
+/* Action to do when background computation completed.
+ *
+ * Wait for all the awaited computations to be over.
+ */
+
+static gint histo_background_ready(void *hook_data, void *call_data)
+{
+  HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData *)hook_data;
+  LttvTrace *trace = (LttvTrace*)call_data;
+
+  histoDrawing_t *drawing = histocontrol_flow_data->drawing;
+  histocontrol_flow_data->background_info_waiting--;
+  
+  if(histocontrol_flow_data->background_info_waiting == 0) {
+    g_message("Histocontrol flow viewer : background computation data ready.");
+
+    histo_drawing_clear(drawing,0,drawing->width);
+    
+    gtk_widget_set_size_request(drawing->drawing_area,
+                -1, -1);
+    histo_redraw_notify(histocontrol_flow_data, NULL);
+  }
+
+  return 0;
+}
+
+
+/* Request background computation. Verify if it is in progress or ready first.
+ * Only for each trace in the tab's traceset.
+ */
+static void histo_request_background_data(HistoControlFlowData *histocontrol_flow_data)
+{
+  LttvTracesetContext * tsc =
+        lttvwindow_get_traceset_context(histocontrol_flow_data->tab);
+  gint num_traces = lttv_traceset_number(tsc->ts);
+  gint i;
+  LttvTrace *trace;
+
+  LttvHooks *histo_background_ready_hook = 
+    lttv_hooks_new();
+  lttv_hooks_add(histo_background_ready_hook, histo_background_ready, histocontrol_flow_data,
+      LTTV_PRIO_DEFAULT);
+  histocontrol_flow_data->background_info_waiting = 0;
+  
+  for(i=0;i<num_traces;i++) {
+    trace = lttv_traceset_get(tsc->ts, i);
+
+    if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace)==FALSE) {
+
+      if(lttvwindowtraces_get_in_progress(g_quark_from_string("state"),
+                                          trace) == FALSE) {
+        /* We first remove requests that could have been done for the same
+         * information. Happens when two viewers ask for it before servicing
+         * starts.
+         */
+        if(!lttvwindowtraces_background_request_find(trace, "state"))
+          lttvwindowtraces_background_request_queue(
+              main_window_get_widget(histocontrol_flow_data->tab), trace, "state");
+        lttvwindowtraces_background_notify_queue(histocontrol_flow_data,
+                                                 trace,
+                                                 ltt_time_infinite,
+                                                 NULL,
+                                                 histo_background_ready_hook);
+        histocontrol_flow_data->background_info_waiting++;
+      } else { /* in progress */
+      
+        lttvwindowtraces_background_notify_current(histocontrol_flow_data,
+                                                   trace,
+                                                   ltt_time_infinite,
+                                                   NULL,
+                                                   histo_background_ready_hook);
+        histocontrol_flow_data->background_info_waiting++;
+      }
+    } else {
+      /* Data ready. Be its nature, this viewer doesn't need to have
+       * its data ready hook called there, because a background
+       * request is always linked with a redraw.
+       */
+    }
+    
+  }
+
+  lttv_hooks_destroy(histo_background_ready_hook);
+}
+
+/**
+ * Histogram Viewer's constructor hook
+ *
+ * This constructor is given as a parameter to the menuitem and toolbar button
+ * registration. It creates the list.
+ * @param tab A pointer to the parent tab.
+ * @return The widget created.
+ */
+GtkWidget *
+h_guihistocontrolflow(Tab *tab)
+{
+  g_info("h_guihistocontrolflow, %p", tab);
+  HistoControlFlowData *histocontrol_flow_data = guihistocontrolflow(tab) ;
+  
+  histocontrol_flow_data->tab = tab;
+  
+  // Unreg done in the GuiHistoControlFlow_Destructor
+  lttvwindow_register_traceset_notify(tab,
+        histo_traceset_notify,
+        histocontrol_flow_data);
+    
+  lttvwindow_register_time_window_notify(tab,
+                                         histo_update_time_window_hook,
+                                         histocontrol_flow_data);
+  lttvwindow_register_current_time_notify(tab,
+                                          histo_update_current_time_hook,
+                                          histocontrol_flow_data);
+  lttvwindow_register_redraw_notify(tab,
+                                    histo_redraw_notify,
+                                    histocontrol_flow_data);
+  lttvwindow_register_continue_notify(tab,
+                                      histo_continue_notify,
+                                      histocontrol_flow_data);
+  //added for histogram, enable filter:
+  lttvwindow_register_filter_notify(tab,
+                histo_filter_changed,histocontrol_flow_data );
+  histocontrol_flow_data->histo_main_win_filter = lttvwindow_get_filter(tab);
+
+//  histo_request_background_data(histocontrol_flow_data);
+  return guihistocontrolflow_get_widget(histocontrol_flow_data) ;
+  
+}
+
+
+/// added for histogram.
+void histo_request_event( HistoControlFlowData *histocontrol_flow_data, guint x, guint width)
+{
+  if(width < 0) return ;
+  
+  guint i, nb_trace;
+  Tab *tab = histocontrol_flow_data->tab;
+  TimeWindow time_window = lttvwindow_get_time_window( tab );
+  LttTime time_start, time_end;
+
+  LttvTraceState *ts;
+  
+  //find the tracehooks 
+  LttvTracesetContext *tsc = lttvwindow_get_traceset_context(tab);
+  
+  LttvTraceset *traceset = tsc->ts;
+  nb_trace = lttv_traceset_number(traceset);
+  guint drawing_width= histocontrol_flow_data->drawing->width;
+//start time for chunk.
+  histo_convert_pixels_to_time(drawing_width, /*0*/x, time_window,
+        &time_start);
+//end time for chunk.
+  histo_convert_pixels_to_time(drawing_width, 
+        /*width*/x+width,time_window,
+       &time_end);
+  time_end = ltt_time_add(time_end, ltt_time_one); // because main window
+                                                   // doesn't deliver end time.
+  lttvwindow_events_request_remove_all(tab,
+                                       histocontrol_flow_data);
+
+  // LttvHooksById *histo_event_by_id = lttv_hooks_by_id_new();//if necessary for filter!
+  // FIXME : eventually request for more traces 
+  for(i = 0; i<MIN(TRACE_NUMBER+1, nb_trace);i++)
+  {   
+       //should be in the loop or before? 
+       EventsRequest *histo_events_request = g_new(EventsRequest, 1);
+       
+       LttvHooks  *histo_before_trace_hooks = lttv_hooks_new();
+       lttv_hooks_add(histo_before_trace_hooks, histo_before_trace,
+                      histo_events_request, LTTV_PRIO_DEFAULT);
+  
+       LttvHooks *histo_count_event_hooks = lttv_hooks_new();
+       lttv_hooks_add(histo_count_event_hooks, histo_count_event,
+                      histo_events_request, LTTV_PRIO_DEFAULT);
+       LttvHooks *histo_after_trace_hooks = lttv_hooks_new();
+       lttv_hooks_add(histo_after_trace_hooks, histo_after_trace, 
+                      histo_events_request, LTTV_PRIO_DEFAULT);
+  
+       //for chunk:
+        LttvHooks *histo_before_chunk_traceset = lttv_hooks_new();
+        LttvHooks *histo_after_chunk_traceset  = lttv_hooks_new();
+
+       lttv_hooks_add(histo_before_chunk_traceset,
+                     histo_before_chunk,
+                     histo_events_request,
+                     LTTV_PRIO_DEFAULT);
+
+        lttv_hooks_add(histo_after_chunk_traceset,
+                     histo_after_chunk,
+                     histo_events_request,
+                     LTTV_PRIO_DEFAULT);
+       ts = (LttvTraceState *)tsc->traces[i];
+      // Fill the events request
+       histo_events_request->owner                 = histocontrol_flow_data; 
+       histo_events_request->viewer_data           = histocontrol_flow_data; 
+       histo_events_request->servicing             = FALSE;     
+       histo_events_request->start_time            = time_start;//time_window.start_time;
+         
+       histo_events_request->start_position        = NULL;
+       histo_events_request->stop_flag             = FALSE;
+       histo_events_request->end_time              = time_end;//time_window.end_time;
+       
+       histo_events_request->num_events            = G_MAXUINT;      
+       histo_events_request->end_position          = NULL; 
+       histo_events_request->trace                 = i;    
+       histo_events_request->hooks                 = NULL; 
+       histo_events_request->before_chunk_traceset = histo_before_chunk_traceset;//NULL; 
+       histo_events_request->before_chunk_trace    = NULL; 
+       histo_events_request->before_chunk_tracefile= NULL; 
+       histo_events_request->event                 = histo_count_event_hooks; 
+       histo_events_request->event_by_id           = NULL;//histo_event_by_id;//NULL; 
+       histo_events_request->after_chunk_tracefile = NULL; 
+       histo_events_request->after_chunk_trace     = NULL;   
+       histo_events_request->after_chunk_traceset  = histo_after_chunk_traceset;//NULL; 
+       histo_events_request->before_request        = histo_before_trace_hooks; 
+       histo_events_request->after_request         = histo_after_trace_hooks; 
+  
+       lttvwindow_events_request(histocontrol_flow_data->tab, histo_events_request);
+  }
+return;
+}
+
+//hook,added for histogram
+int histo_count_event(void *hook_data, void *call_data){
+
+  guint x;//time to pixel
+  guint i;// number of events
+  LttTime  event_time; 
+  LttEvent *e;
+  guint *element;
+   
+  EventsRequest *events_request = (EventsRequest*)hook_data;
+  HistoControlFlowData *histocontrol_flow_data = events_request->viewer_data;
+  
+  histoDrawing_t *drawing = histocontrol_flow_data->drawing;
+  int width = drawing->width;  
+  
+  g_info("Histogram: count_event() \n");
+  
+   
+  LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
+  LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+
+  e = ltt_tracefile_get_event(tfc->tf);
+
+  LttvFilter *histo_filter = histocontrol_flow_data->histo_main_win_filter;
+  if(histo_filter != NULL && histo_filter->head != NULL)
+    if(!lttv_filter_tree_parse(histo_filter->head,e,tfc->tf,
+          tfc->t_context->t,tfc))
+      return FALSE;
+
+  TimeWindow time_window  =  lttvwindow_get_time_window(histocontrol_flow_data->tab);
+  event_time = ltt_event_time(e);
+  
+  histo_convert_time_to_pixels(
+          time_window,
+          event_time,
+          width,
+          &x);
+  element = &g_array_index(histocontrol_flow_data->number_of_process, guint, x);
+  (*element)++;
+
+  return 0;
+}
+///befor hook:Added for histogram
+int histo_before_trace(void *hook_data, void *call_data){
+
+  EventsRequest *events_request = (EventsRequest*)hook_data;
+  HistoControlFlowData *histocontrol_flow_data = events_request->viewer_data;
+    
+  histoDrawing_t *drawing = histocontrol_flow_data->drawing;
+  
+//in order to reset all of the array elements.
+  guint i,end;
+  end = MIN(histocontrol_flow_data->number_of_process->len,drawing->damage_end);
+  for(i=drawing->damage_begin/*0*/; 
+       i < end/*histocontrol_flow_data->number_of_process->len*/;i++) 
+  {
+    g_array_index(histocontrol_flow_data->number_of_process, guint, i) = 0;
+  }
+  histo_drawing_clear(drawing,drawing->damage_begin/*0*/,
+               drawing->damage_end - drawing->damage_begin/*drawing->width*/);
+  //g_array_free(histocontrol_flow_data->number_of_process,TRUE);
+  //histocontrol_flow_data->number_of_process =g_array_new (FALSE,
+  //                                           TRUE,
+  //                                           sizeof(guint));//4 byte for guint
+  //g_array_set_size (histocontrol_flow_data->number_of_process,
+  //                                           drawing->drawing_area->allocation.width);
+//  gtk_widget_set_size_request(drawing->drawing_area,-1,-1);
+  gtk_widget_queue_draw(drawing->drawing_area);
+   return 0;
+}
+//after hook,added for histogram
+int histo_after_trace(void *hook_data, void *call_data){
+
+  EventsRequest *events_request = (EventsRequest*)hook_data;
+  HistoControlFlowData *histocontrol_flow_data = events_request->viewer_data;
+  histoDrawing_t *drawing = histocontrol_flow_data->drawing;
+  guint x, x_end, width;
+  LttTime end_time = events_request->end_time;
+  TimeWindow time_window = 
+        lttvwindow_get_time_window(histocontrol_flow_data->tab);
+
+  g_debug("histo after trace");
+  
+  histo_convert_time_to_pixels(
+        time_window,
+        end_time,
+        drawing->width,
+        &x_end);
+  x = drawing->damage_begin;
+  width = x_end - x;
+  drawing->damage_begin = x+width;
+  histogram_show (histocontrol_flow_data,x,x_end);
+  
+   return 0;
+}
+
+void histogram_show(HistoControlFlowData *histocontrol_flow_data,guint draw_begin,
+                   guint draw_end)
+{
+  histoDrawing_t *drawing = histocontrol_flow_data->drawing;
+  GtkWidget *drawingarea= histo_drawing_get_drawing_area(drawing);
+  guint width = drawing->width;
+  guint height= drawing->height;//drawingarea->allocation.height;
+  
+ /* gdk_gc_set_line_attributes(drawing->gc,
+                               2,
+                               GDK_LINE_SOLID,
+                               GDK_CAP_BUTT,
+                               GDK_JOIN_MITER);*/
+//clean the area!
+  histo_drawing_clear(drawing,draw_begin,draw_end);
+  LttTime t1,t2;
+  TimeWindow time_window =
+              lttvwindow_get_time_window(histocontrol_flow_data->tab);
+     
+  guint val,h_val;
+  
+  guint i,line_src,line_end;
+  guint end_chunk=MIN(draw_end,(histocontrol_flow_data->number_of_process)->len);
+  
+  for (i=draw_begin/*0*/;i<end_chunk/* (histocontrol_flow_data->number_of_process)->len*/;i++){
+       val=g_array_index(histocontrol_flow_data->number_of_process,guint,i);
+       h_val= height-((height*val)/histocontrol_flow_data->max_height);
+       
+       histo_convert_pixels_to_time(width, i,
+               time_window,
+               &t1);
+       histo_convert_pixels_to_time(width, i+1,
+               time_window,
+               &t2);
+       line_src=i;
+       
+//check if zoom in is used and more than 1 pixel correspond to each 1nsec
+//used for drawing point (not line) on the screen.
+/*     while (ltt_time_compare(t1,t2)==0)
+       {
+               histo_convert_pixels_to_time(width, i++,
+               time_window,
+               &t1);
+               histo_convert_pixels_to_time(width, i+1,
+               time_window,
+               &t2);
+               
+       
+       }//while (t1==t2)
+*/ //replaced later for lines.
+
+   if(val > drawing->histo_control_flow_data->max_height){
+       //overlimit, yellow color               
+       gdk_gc_set_foreground(drawing->gc,&histo_drawing_colors[COL_WHITE] );//COL_RUN_TRAP
+        gdk_draw_line (drawing->pixmap,
+                              drawing->gc,
+                              i/*line_src*/,1,
+                              i,/*1*/height);
+   }
+   else{
+       gdk_gc_set_foreground(drawing->gc,&histo_drawing_colors[COL_RUN_USER_MODE] );
+       gdk_draw_line (drawing->pixmap,
+                              drawing->gc,
+                             i/*line_src*/,h_val,
+                              i,/*h_val*/height);
+       }
+
+  while ((ltt_time_compare(t1,t2)==0)&&(i<end_chunk))//-1 , i to be incremented later 
+   {////
+       i++;
+               
+       if(val > drawing->histo_control_flow_data->max_height){
+               //overlimit, yellow color               
+               gdk_gc_set_foreground(drawing->gc,
+                       &histo_drawing_colors[COL_RUN_TRAP] );
+               gdk_draw_line (drawing->pixmap,
+                              drawing->gc,
+                              i,1,
+                              i,height);
+       }
+       else{
+               gdk_gc_set_foreground(drawing->gc,&histo_drawing_colors[COL_RUN_USER_MODE] );
+               gdk_draw_line (drawing->pixmap,
+                              drawing->gc,
+                              i,h_val,
+                              i,height);
+       }
+       histo_convert_pixels_to_time(width, i,
+               time_window,
+               &t1);
+       if(i<end_chunk-1){
+               histo_convert_pixels_to_time(width, i+1,
+                       time_window,
+                       &t2);
+       }
+    }//while (t1==t2)////
+     
+  }
+   
+   histo_drawing_update_vertical_ruler(drawing);
+   gtk_widget_queue_draw_area ( drawing->drawing_area,
+                               draw_begin, 0,
+                               draw_end-draw_begin, drawing->height);
+   gdk_window_process_updates(drawingarea->window,TRUE);
+}
+
+int histo_event_selected_hook(void *hook_data, void *call_data)
+{
+  HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData*) hook_data;
+  guint *event_number = (guint*) call_data;
+
+  g_debug("DEBUG : event selected by main window : %u", *event_number);
+  
+  return 0;
+}
+
+
+
+/* histo_before_schedchange_hook
+ * 
+ * This function basically draw lines and icons. Two types of lines are drawn :
+ * one small (3 pixels?) representing the state of the process and the second
+ * type is thicker (10 pixels?) representing on which CPU a process is running
+ * (and this only in running state).
+ *
+ * Extremums of the lines :
+ * x_min : time of the last event context for this process kept in memory.
+ * x_max : time of the current event.
+ * y : middle of the process in the process list. The process is found in the
+ * list, therefore is it's position in pixels.
+ *
+ * The choice of lines'color is defined by the context of the last event for this
+ * process.
+ */
+
+/*
+int histo_before_schedchange_hook(void *hook_data, void *call_data)
+{
+   return 0;
+}
+*/
+gint histo_update_time_window_hook(void *hook_data, void *call_data)
+{
+  HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData*) hook_data;
+  histoDrawing_t *drawing = histocontrol_flow_data->drawing;
+  
+  const TimeWindowNotifyData *histo_time_window_nofify_data = 
+                          ((const TimeWindowNotifyData *)call_data);
+
+  TimeWindow *histo_old_time_window = 
+    histo_time_window_nofify_data->old_time_window;
+  TimeWindow *histo_new_time_window = 
+    histo_time_window_nofify_data->new_time_window;
+  
+  // Update the ruler 
+  histo_drawing_update_ruler(drawing,
+                       histo_new_time_window);
+
+  /* Two cases : zoom in/out or scrolling */
+  
+  /* In order to make sure we can reuse the old drawing, the scale must
+   * be the same and the new time interval being partly located in the
+   * currently shown time interval. (reuse is only for scrolling)
+   */
+
+  g_info("Old time window HOOK : %lu, %lu to %lu, %lu",
+      histo_old_time_window->start_time.tv_sec,
+      histo_old_time_window->start_time.tv_nsec,
+      histo_old_time_window->time_width.tv_sec,
+      histo_old_time_window->time_width.tv_nsec);
+
+  g_info("New time window HOOK : %lu, %lu to %lu, %lu",
+      histo_new_time_window->start_time.tv_sec,
+      histo_new_time_window->start_time.tv_nsec,
+      histo_new_time_window->time_width.tv_sec,
+      histo_new_time_window->time_width.tv_nsec);
+
+ //For Histo,redraw always except if zoom fit is pushed 2 times consequently
+ if( histo_new_time_window->start_time.tv_sec == histo_old_time_window->start_time.tv_sec
+  && histo_new_time_window->start_time.tv_nsec == histo_old_time_window->start_time.tv_nsec
+  && histo_new_time_window->time_width.tv_sec == histo_old_time_window->time_width.tv_sec
+  && histo_new_time_window->time_width.tv_nsec == histo_old_time_window->time_width.tv_nsec)
+  {
+       return 0;  
+  }   
+  histo_rectangle_pixmap (drawing->drawing_area->style->black_gc,
+          TRUE,
+          0, 0,
+          drawing->width,//+SAFETY, // do not overlap
+          -1,drawing);
+
+    drawing->damage_begin = 0;
+    drawing->damage_end = drawing->width;
+
+    gtk_widget_queue_draw(drawing->drawing_area);
+    histo_request_event(histocontrol_flow_data,drawing->damage_begin,
+                       drawing->damage_end- drawing->damage_begin);
+  
+  gdk_window_process_updates(drawing->drawing_area->window,TRUE);
+
+//show number of event at current time 
+
+  histo_drawing_update_vertical_ruler(drawing);
+
+
+
+/*//  if( histo_new_time_window->time_width.tv_sec == histo_old_time_window->time_width.tv_sec
+  && histo_new_time_window->time_width.tv_nsec == histo_old_time_window->time_width.tv_nsec)
+  {
+    // Same scale (scrolling) 
+    g_info("scrolling");
+    /* For histogram,
+      while scrolling no matter far or near , 
+      right or left it's necessary to redraw whole screen!*/
+/*//    LttTime *ns = &histo_new_time_window->start_time;
+    LttTime *nw = &histo_new_time_window->time_width;
+    LttTime *os = &histo_old_time_window->start_time;
+    LttTime *ow = &histo_old_time_window->time_width;
+    LttTime histo_old_end = histo_old_time_window->end_time;
+    LttTime histo_new_end = histo_new_time_window->end_time;
+    //if(ns<os+w<ns+w)
+    //if(ns<os+w && os+w<ns+w)
+    //if(ns<histo_old_end && os<ns)
+
+    //added for histogram
+    gtk_widget_queue_draw(drawing->drawing_area);
+
+          drawing->damage_begin = 0;
+          drawing->damage_end = drawing->width;
+
+      //replaced for hisogram
+      histo_request_event(histocontrol_flow_data,drawing->damage_begin,
+                       drawing->damage_end- drawing->damage_begin);
+/*  
+    if(ltt_time_compare(*ns, histo_old_end) == -1
+        && ltt_time_compare(*os, *ns) == -1)
+    {
+      g_info("scrolling near right");
+      // Scroll right, keep right part of the screen 
+      guint x = 0;
+      guint width = drawing->width;
+      histo_convert_time_to_pixels(
+          *histo_old_time_window,
+          *ns,
+          width,
+          &x);
+
+      // Copy old data to new location 
+      //replaced for histogram:
+       histo_copy_pixmap_region(drawing,NULL,
+               drawing->drawing_area->style->black_gc,//drawing->gc,
+               NULL,
+               x, 0,
+               0, 0, (drawing->width-x)
+               , -1);
+  
+    if(drawing->damage_begin == drawing->damage_end)
+        drawing->damage_begin = drawing->width-x;
+      else
+        drawing->damage_begin = 0;
+
+      drawing->damage_end = drawing->width;
+
+//(histo) copy corresponding array region too:
+  guint i;
+  
+  for(i=0; i < histocontrol_flow_data->number_of_process->len-x;i++) 
+  {
+      g_array_index(histocontrol_flow_data->number_of_process, guint, i) = 
+         g_array_index(histocontrol_flow_data->number_of_process, guint, i+x);
+  }
+
+      // Clear the data request background, but not SAFETY 
+
+//not necessary for histo, because in before chunk ,it clears the area
+/*     histo_rectangle_pixmap (
+       drawing->drawing_area->style->black_gc,
+          TRUE,
+          drawing->damage_begin, 0,
+          drawing->damage_end - drawing->damage_begin,  // do not overlap
+          -1,drawing);
+*/
+ /*     gtk_widget_queue_draw(drawing->drawing_area);
+      //gtk_widget_queue_draw_area (drawing->drawing_area,
+      //                          0,0,
+      //                          histocontrol_flow_data->drawing->width,
+      //                          histocontrol_flow_data->drawing->height);
+
+    // Get new data for the rest.
+    //replaced for hisogram 
+      histo_request_event(histocontrol_flow_data,drawing->damage_begin,
+                       drawing->damage_end- drawing->damage_begin);
+    } else { 
+      //if(ns<os<ns+w)
+      //if(ns<os && os<ns+w)
+      //if(ns<os && os<histo_new_end)
+      if(ltt_time_compare(*ns,*os) == -1
+          && ltt_time_compare(*os,histo_new_end) == -1)
+      {
+        g_info("scrolling near left");
+        // Scroll left, keep left part of the screen 
+        guint x = 0;
+        guint width = drawing->width;
+        histo_convert_time_to_pixels(
+            *histo_new_time_window,
+            *os,
+            width,
+            &x);
+        
+        // Copy old data to new location 
+       //replaced for histogram
+
+       histo_copy_pixmap_region(drawing,NULL,
+               drawing->drawing_area->style->black_gc,//drawing->gc,
+               NULL,
+               0, 0,
+               x, 0, -1, -1);
+       //(histo) copy corresponding array region too:
+       guint i;
+       for(i=histocontrol_flow_data->number_of_process->len; i > x-1;i--) 
+       {
+        g_array_index(histocontrol_flow_data->number_of_process, guint, i) = 
+         g_array_index(histocontrol_flow_data->number_of_process, guint, i-x);
+       }
+
+       if(drawing->damage_begin == drawing->damage_end)
+          drawing->damage_end = x;
+        else
+          drawing->damage_end = 
+            drawing->width;
+
+        drawing->damage_begin = 0;
+
+        
+//not necessary for histo, because in before chunk ,it clears the area
+  /*      histo_rectangle_pixmap (drawing->drawing_area->style->black_gc,
+          TRUE,
+          drawing->damage_begin, 0,
+          drawing->damage_end - drawing->damage_begin,  // do not overlap
+          -1,drawing);
+*/
+ /*       gtk_widget_queue_draw(drawing->drawing_area);
+        //gtk_widget_queue_draw_area (drawing->drawing_area,
+        //                        0,0,
+        //                        histocontrol_flow_data->drawing->width,
+        //                        histocontrol_flow_data->drawing->height);
+
+
+        // Get new data for the rest. 
+
+//replaced for hisogram
+      histo_request_event(histocontrol_flow_data,drawing->damage_begin,
+                       drawing->damage_end- drawing->damage_begin);
+    
+      } else {
+        if(ltt_time_compare(*ns,*os) == 0)
+        {
+          g_info("not scrolling");
+        } else {
+          g_info("scrolling far");
+          // Cannot reuse any part of the screen : far jump 
+          
+          //not necessary for histo, because in before chunk ,it clears the area
+ /*         histo_rectangle_pixmap (histocontrol_flow_data->drawing->drawing_area->style->black_gc,
+            TRUE,
+            0, 0,
+            histocontrol_flow_data->drawing->width,//+SAFETY, // do not overlap
+            -1,drawing);
+*/
+          //gtk_widget_queue_draw_area (drawing->drawing_area,
+          //                      0,0,
+          //                      histocontrol_flow_data->drawing->width,
+          //                      histocontrol_flow_data->drawing->height);
+/*          gtk_widget_queue_draw(drawing->drawing_area);
+
+          drawing->damage_begin = 0;
+          drawing->damage_end = histocontrol_flow_data->drawing->width;
+/*
+          histo_drawing_data_request(histocontrol_flow_data->drawing,
+              0, 0,
+              histocontrol_flow_data->drawing->width,
+              histocontrol_flow_data->drawing->height);*/
+      //replaced for hisogram
+ /*     histo_request_event(histocontrol_flow_data,drawing->damage_begin,
+                       drawing->damage_end- drawing->damage_begin);
+        }
+      }
+    }
+  } else {
+    // Different scale (zoom) 
+    g_info("zoom");
+
+ //not necessary for histo, because in before chunk ,it clears the area
+ /*
+    histo_rectangle_pixmap (drawing->drawing_area->style->black_gc,
+          TRUE,
+          0, 0,
+          histocontrol_flow_data->drawing->width+SAFETY, // do not overlap
+          -1,drawing);
+*/
+    //gtk_widget_queue_draw_area (drawing->drawing_area,
+    //                            0,0,
+    //                            histocontrol_flow_data->drawing->width,
+    //                            histocontrol_flow_data->drawing->height);
+/*//    gtk_widget_queue_draw(drawing->drawing_area);
+  
+    drawing->damage_begin = 0;
+    drawing->damage_end = drawing->width;
+
+  //replaced for hisogram
+   histo_request_event(histocontrol_flow_data,drawing->damage_begin,
+                       drawing->damage_end- drawing->damage_begin);
+  }
+
+  // Update directly when scrolling 
+  gdk_window_process_updates(drawing->drawing_area->window,
+      TRUE);
+
+  //show number of event at current time 
+
+  histo_drawing_update_vertical_ruler(drawing);
+*/
+//disabled for histogram, always redraw whole screen. 
+  return 0;
+}
+
+gint histo_traceset_notify(void *hook_data, void *call_data)
+{
+  HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData*) hook_data;
+  histoDrawing_t *drawing = histocontrol_flow_data->drawing;
+
+  if(unlikely(drawing->gc == NULL)) {
+    return FALSE;
+  }
+  if(drawing->dotted_gc == NULL) {
+    return FALSE;
+  }
+
+  histo_drawing_clear(drawing,0,drawing->width);
+  
+  guint i;
+  for(i=0;i < histocontrol_flow_data->number_of_process->len;i++) 
+  {
+    g_array_index(histocontrol_flow_data->number_of_process, guint, i) = 0;
+  }
+  gtk_widget_set_size_request(
+      drawing->drawing_area,
+                -1, -1);
+  histo_redraw_notify(histocontrol_flow_data, NULL);
+
+  ///histo_request_background_data(histocontrol_flow_data);
+  return FALSE;
+}
+
+gint histo_redraw_notify(void *hook_data, void *call_data)
+{
+  HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData*) hook_data;
+  histoDrawing_t *drawing = histocontrol_flow_data->drawing;
+  GtkWidget *widget = drawing->drawing_area;
+
+  drawing->damage_begin = 0;
+  drawing->damage_end = drawing->width;
+
+  // fun feature, to be separated someday... 
+  
+  histo_drawing_clear(drawing,0,drawing->width);
+  
+  gtk_widget_set_size_request(
+      drawing->drawing_area,
+                -1, -1);
+  // Clear the images
+  
+  histo_rectangle_pixmap (widget->style->black_gc,
+        TRUE,
+        0, 0,
+        drawing->alloc_width,
+        -1,drawing);
+  gtk_widget_queue_draw(widget);
+  
+  if(drawing->damage_begin < drawing->damage_end)
+  {
+       //replaced for histogram 
+       histo_request_event(histocontrol_flow_data,0,drawing->width);
+  }
+  
+
+  //gtk_widget_queue_draw_area(drawing->drawing_area,
+  //                           0,0,
+  //                           drawing->width,
+  //                           drawing->height);
+  return FALSE;
+
+}
+
+
+gint histo_continue_notify(void *hook_data, void *call_data)
+{
+  HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData*) hook_data;
+  histoDrawing_t *drawing = histocontrol_flow_data->drawing;
+
+  //g_assert(widget->allocation.width == drawing->damage_end);
+  
+  if(drawing->damage_begin < drawing->damage_end)
+  {
+       histo_request_event(histocontrol_flow_data,drawing->damage_begin,
+                           drawing->damage_end-drawing->damage_begin);
+  }
+
+  return FALSE;
+}
+
+
+gint histo_update_current_time_hook(void *hook_data, void *call_data)
+{
+  HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData*)hook_data;
+  histoDrawing_t *drawing = histocontrol_flow_data->drawing;
+
+  LttTime current_time = *((LttTime*)call_data);
+  
+  TimeWindow time_window =
+            lttvwindow_get_time_window(histocontrol_flow_data->tab);
+  
+  LttTime time_begin = time_window.start_time;
+  LttTime width = time_window.time_width;
+  LttTime half_width;
+  {
+    guint64 time_ll = ltt_time_to_uint64(width);
+    time_ll = time_ll >> 1; /* divide by two */
+    half_width = ltt_time_from_uint64(time_ll);
+  }
+  LttTime time_end = ltt_time_add(time_begin, width);
+
+  LttvTracesetContext * tsc =
+        lttvwindow_get_traceset_context(histocontrol_flow_data->tab);
+  
+  LttTime trace_start = tsc->time_span.start_time;
+  LttTime trace_end = tsc->time_span.end_time;
+  
+  g_info("Histogram: New current time HOOK : %lu, %lu", current_time.tv_sec,
+              current_time.tv_nsec);
+
+
+  
+  /* If current time is inside time interval, just move the highlight
+   * bar */
+
+  /* Else, we have to change the time interval. We have to tell it
+   * to the main window. */
+  /* The time interval change will take care of placing the current
+   * time at the center of the visible area, or nearest possible if we are
+   * at one end of the trace. */
+  
+  
+  if(ltt_time_compare(current_time, time_begin) < 0)
+  {
+    TimeWindow histo_new_time_window;
+
+    if(ltt_time_compare(current_time,
+          ltt_time_add(trace_start,half_width)) < 0)
+      time_begin = trace_start;
+    else
+      time_begin = ltt_time_sub(current_time,half_width);
+  
+    histo_new_time_window.start_time = time_begin;
+    histo_new_time_window.time_width = width;
+    histo_new_time_window.time_width_double = ltt_time_to_double(width);
+    histo_new_time_window.end_time = ltt_time_add(time_begin, width);
+
+    lttvwindow_report_time_window(histocontrol_flow_data->tab, histo_new_time_window);
+  }
+  else if(ltt_time_compare(current_time, time_end) > 0)
+  {
+    TimeWindow histo_new_time_window;
+
+    if(ltt_time_compare(current_time, ltt_time_sub(trace_end, half_width)) > 0)
+      time_begin = ltt_time_sub(trace_end,width);
+    else
+      time_begin = ltt_time_sub(current_time,half_width);
+  
+    histo_new_time_window.start_time = time_begin;
+    histo_new_time_window.time_width = width;
+    histo_new_time_window.time_width_double = ltt_time_to_double(width);
+    histo_new_time_window.end_time = ltt_time_add(time_begin, width);
+
+    lttvwindow_report_time_window(histocontrol_flow_data->tab, histo_new_time_window);
+    
+  }
+  gtk_widget_queue_draw(drawing->drawing_area);
+  
+  /* Update directly when scrolling */
+  gdk_window_process_updates(drawing->drawing_area->window,
+      TRUE);
+
+  histo_drawing_update_vertical_ruler(drawing);
+                         
+  return 0;
+}
+
+gboolean histo_filter_changed(void * hook_data, void * call_data)
+{
+  HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData*)hook_data;
+  histoDrawing_t *drawing =histocontrol_flow_data->drawing;
+
+  LttvTracesetContext * tsc =
+        lttvwindow_get_traceset_context(histocontrol_flow_data->tab);
+
+  histocontrol_flow_data->histo_main_win_filter = 
+    (LttvFilter*)call_data;
+  //get_events(event_viewer_data->vadjust_c->value, event_viewer_data);
+  gtk_widget_set_size_request(
+      drawing->drawing_area,
+                -1, -1);
+  drawing->damage_begin = 0;
+  drawing->damage_end = drawing->width;
+
+ /* //done in, before request!
+  histo_drawing_clear(drawing,0,drawing->width);
+  guint i;
+  for(i=0;i < histocontrol_flow_data->number_of_process->len;i++) 
+  {
+    g_array_index(histocontrol_flow_data->number_of_process, guint, i) = 0;
+  }*/
+  histo_request_event(histocontrol_flow_data,0,drawing->width);
+  
+  return FALSE;
+}
+
+typedef struct _histo_ClosureData {
+  EventsRequest *events_request;
+  LttvTracesetState *tss;
+  LttTime end_time;
+  guint x_end;
+} histo_ClosureData;
+  
+
+
+int histo_before_chunk(void *hook_data, void *call_data)
+{
+  EventsRequest *histo_events_request = (EventsRequest*)hook_data;
+  LttvTracesetState *histo_tss = (LttvTracesetState*)call_data;
+  HistoControlFlowData *histo_cfd = (HistoControlFlowData*)histo_events_request->viewer_data;
+#if 0  
+  /* Desactivate sort */
+  gtk_tree_sortable_set_sort_column_id(
+      GTK_TREE_SORTABLE(cfd->process_list->list_store),
+      TRACE_COLUMN,
+      GTK_SORT_ASCENDING);
+#endif //0
+  histo_drawing_chunk_begin(histo_events_request, histo_tss);
+
+  return 0;
+}
+
+/*int histo_before_request(void *hook_data, void *call_data)
+{
+  EventsRequest *events_request = (EventsRequest*)hook_data;
+  LttvTracesetState *tss = (LttvTracesetState*)call_data;
+  histo_drawing_data_request_begin(events_request, tss);
+
+  return 0;
+}
+*/
+
+
+/*
+ * after request is necessary in addition of after chunk in order to draw 
+ * lines until the end of the screen. after chunk just draws lines until
+ * the last event.
+ * 
+ * for each process
+ *    draw closing line
+ *    expose
+ */
+/*int histo_after_request(void *hook_data, void *call_data)
+{
+  return 0;
+}
+*/
+/*
+ * for each process
+ *    draw closing line
+ * expose
+ */
+
+int histo_after_chunk(void *hook_data, void *call_data)
+{
+  EventsRequest *events_request = (EventsRequest*)hook_data;
+  HistoControlFlowData *histocontrol_flow_data = events_request->viewer_data;
+  LttvTracesetState *tss = (LttvTracesetState*)call_data;
+  LttvTracesetContext *tsc = (LttvTracesetContext*)call_data;
+  LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
+  LttTime end_time;
+
+  histoDrawing_t *drawing = histocontrol_flow_data->drawing;
+
+  if(tfc != NULL)
+    end_time = LTT_TIME_MIN(tfc->timestamp, events_request->end_time);
+  else /* end of traceset, or position now out of request : end */
+    end_time = events_request->end_time;
+  
+  guint x, x_end, width;
+  
+  TimeWindow time_window = 
+        lttvwindow_get_time_window(histocontrol_flow_data->tab);
+
+  g_debug("histo after chunk");
+
+  histo_convert_time_to_pixels(
+        time_window,
+        end_time,
+        drawing->width,
+        &x_end);
+  x = drawing->damage_begin;
+  width = x_end - x;
+  drawing->damage_begin = x+width;
+
+  histogram_show (histocontrol_flow_data,x,x_end);
+  
+  return 0;
+}
+
diff --git a/ltt/branches/poly/lttv/modules/gui/histogram/histoeventhooks.h b/ltt/branches/poly/lttv/modules/gui/histogram/histoeventhooks.h
new file mode 100644 (file)
index 0000000..e8a49be
--- /dev/null
@@ -0,0 +1,128 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2006 Parisa heidari (inspired from CFV by 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.
+ */
+
+
+/* eventhooks.h defines the hooks that are given to processTrace as parameter.
+ * These hooks call the drawing API to draw the information on the screen,
+ * using information from Context, but mostly state (running, waiting...).
+ */
+
+
+#ifndef _EVENT_HOOKS_H
+#define _EVENT_HOOKS_H
+
+#include <gtk/gtk.h>
+#include <lttvwindow/mainwindow.h>
+#include <ltt/time.h>
+
+#include "histobuttonwidget.h"
+#include "histodrawing.h"
+#include "histocfv.h"
+
+
+/* Structure used to store and use information relative to one events refresh
+ * request. Typically filled in by the expose event callback, then passed to the
+ * library call, then used by the drawing hooks. Then, once all the events are
+ * sent, it is freed by the hook called after the reading.
+ */
+//typedef struct _EventRequest
+//{
+//  ControlFlowData *control_flow_data;
+//  LttTime time_begin, time_end;
+//  gint  x_begin, x_end;
+  /* Fill the Events_Context during the initial expose, before calling for
+   * events.
+   */
+  //GArray Events_Context; //FIXME
+//} EventRequest ;
+
+
+
+
+
+void send_test_data(ButtonWidget *buttonwidget, histoDrawing_t *drawing);//??
+
+GtkWidget *h_guihistocontrolflow(Tab *tab);
+
+//GtkWidget *h_legend(Tab *tab);
+
+int histo_event_selected_hook(void *hook_data, void *call_data);
+
+/*
+ * The draw event hook is called by the reading API to have a
+ * particular event drawn on the screen.
+ * @param hook_data ControlFlowData structure of the viewer. 
+ * @param call_data Event context with state.
+ *
+ * This function basically draw lines and icons. Two types of lines are drawn :
+ * one small (3 pixels?) representing the state of the process and the second
+ * type is thicker (10 pixels?) representing on which CPU a process is running
+ * (and this only in running state).
+ *
+ * Extremums of the lines :
+ * x_min : time of the last event context for this process kept in memory.
+ * x_max : time of the current event.
+ * y : middle of the process in the process list. The process is found in the
+ * list, therefore is it's position in pixels.
+ *
+ * The choice of lines'color is defined by the context of the last event for this
+ * process.
+ */
+//int histo_before_schedchange_hook(void *hook_data, void *call_data);
+int histo_after_schedchange_hook(void *hook_data, void *call_data);
+int histo_before_execmode_hook(void *hook_data, void *call_data);
+int histo_after_execmode_hook(void *hook_data, void *call_data);
+
+
+int histo_before_process_exit_hook(void *hook_data, void *call_data);
+int histo_before_process_release_hook(void *hook_data, void *call_data);
+int histo_after_process_exit_hook(void *hook_data, void *call_data);
+int histo_after_process_fork_hook(void *hook_data, void *call_data);
+int histo_after_fs_exec_hook(void *hook_data, void *call_data);
+
+
+#if 0
+int before_process_hook(void *hook_data, void *call_data);
+int after_process_hook(void *hook_data, void *call_data);
+#endif //0
+
+//void histo_draw_closure(guint key, gpointer value, gpointer user_data);
+
+int  histo_before_chunk(void *hook_data, void *call_data);
+int  histo_after_chunk(void *hook_data, void *call_data);
+//int  histo_before_request(void *hook_data, void *call_data);
+//int  histo_after_request(void *hook_data, void *call_data);
+
+
+
+gint histo_update_time_window_hook(void *hook_data, void *call_data);
+gint histo_update_current_time_hook(void *hook_data, void *call_data);
+gint histo_traceset_notify(void *hook_data, void *call_data);
+gint histo_redraw_notify(void *hook_data, void *call_data);
+gint histo_continue_notify(void *hook_data, void *call_data);
+
+//just for histogram
+void histo_request_event( HistoControlFlowData *histocontrol_flow_data,guint x, guint width);
+int histo_count_event(void *hook_data, void *call_data);
+int histo_before_trace(void *hook_data, void *call_data);//replaced for histo_before_request
+int histo_after_trace(void *hook_data, void *call_data);//replaced for histo_after_request
+
+gboolean histo_filter_changed(void * hook_data, void * call_data);
+
+void histogram_show(HistoControlFlowData *histocontrol_flow_data,guint draw_begin,guint draw_end);
+#endif // _EVENT_HOOKS_H
diff --git a/ltt/branches/poly/lttv/modules/gui/histogram/histomodule.c b/ltt/branches/poly/lttv/modules/gui/histogram/histomodule.c
new file mode 100644 (file)
index 0000000..c9c5814
--- /dev/null
@@ -0,0 +1,93 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2006 Parisa heidari (inspired from CFV by 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.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <lttv/lttv.h>
+#include <lttv/module.h>
+#include <lttvwindow/lttvwindow.h>
+
+#include "histocfv.h"
+#include "histoeventhooks.h"
+
+#include "hHistogramInsert.xpm"
+
+
+GQuark LTT_NAME_CPU;
+
+/** Array containing instanced objects. Used when module is unloaded */
+GSList *g_histo_control_flow_data_list = NULL ;
+
+/*****************************************************************************
+ *                 Functions for module loading/unloading                    *
+ *****************************************************************************/
+/**
+ * plugin's init function
+ *
+ * This function initializes the Histogram Control Flow Viewer functionnality through the
+ * gtkTraceSet API.
+ */
+static void histo_init() {
+
+  g_info("GUI ControlFlow Viewer init()");
+
+  /* Register the toolbar insert button and menu entry*/
+  lttvwindow_register_constructor("histogram",
+                                  "/",
+                                  "Insert Histogram Viewer",
+                                  hHistogramInsert_xpm,
+                                  "Insert Histogram Viewer",
+                                  h_guihistocontrolflow);
+
+  LTT_NAME_CPU = g_quark_from_string("/cpu");
+}
+
+void histo_destroy_walk(gpointer data, gpointer user_data)
+{
+  g_info("Walk destroy GUI Histogram Control Flow Viewer");
+  guihistocontrolflow_destructor_full((HistoControlFlowData*)data);
+}
+
+
+
+/**
+ * plugin's destroy function
+ *
+ * This function releases the memory reserved by the module and unregisters
+ * everything that has been registered in the gtkTraceSet API.
+ */
+static void histo_destroy() {
+  g_info("GUI Histogram Control Flow Viewer destroy()");
+
+  g_slist_foreach(g_histo_control_flow_data_list, histo_destroy_walk, NULL );
+  
+  g_slist_free(g_histo_control_flow_data_list);
+
+  /* Unregister the toolbar insert button and menu entry */
+  lttvwindow_unregister_constructor(h_guihistocontrolflow);
+  
+}
+
+
+LTTV_MODULE("guihistogram", "Event Histogram viewer", \
+    "Graphical module to view events' density histogram", \
+    histo_init, histo_destroy, "lttvwindow")
diff --git a/ltt/branches/poly/lttv/modules/gui/histogram/stock_zoom_fit_24.xpm b/ltt/branches/poly/lttv/modules/gui/histogram/stock_zoom_fit_24.xpm
new file mode 100644 (file)
index 0000000..bd0b3f4
--- /dev/null
@@ -0,0 +1,216 @@
+/* XPM */
+static char *stock_zoom_fit_24[]={
+"24 24 189 2",
+"Qt c None",
+"ae c #000000",
+"aF c #000000",
+"an c #050505",
+".U c #242424",
+".s c #373737",
+".G c #4f4f4f",
+".h c #5d5d5d",
+"aS c #000000",
+"a6 c #000000",
+"at c #000000",
+"aQ c #000000",
+"ad c #000000",
+"au c #030303",
+"#8 c #0c0c0c",
+"#j c #121212",
+".F c #232323",
+"#. c #303030",
+".g c #353535",
+".t c #404040",
+".# c #494949",
+"aE c #000000",
+"#7 c #000000",
+"#s c #090909",
+"#1 c #0a0a0a",
+"#k c #1b1b1b",
+".f c #262626",
+".a c #343434",
+"am c #000000",
+"aG c #010101",
+"af c #060606",
+".9 c #0f0f0f",
+".r c #1c1c1c",
+".V c #212121",
+".i c #2e2e2e",
+"aR c #000000",
+"#0 c #020202",
+"#A c #060606",
+"#V c #0b0b0b",
+"#t c #141414",
+".e c #262626",
+".b c #2d2d2d",
+"aN c #000000",
+"a4 c #000000",
+"aW c #000000",
+"aO c #000000",
+"aC c #000000",
+"aD c #000000",
+"aP c #000000",
+"aT c #202020",
+"a1 c #000000",
+"aU c #202020",
+"aV c #000000",
+"aY c #343434",
+"a2 c #000000",
+"as c #000000",
+"av c #030303",
+"#U c #050505",
+"#J c #060606",
+"#K c #0e0e0e",
+".T c #101010",
+"#B c #111111",
+".E c #131313",
+"a3 c #1f1f1f",
+".H c #222222",
+".d c #262626",
+".u c #272727",
+".c c #292929",
+"aX c #686868",
+"a0 c #3a3a3a",
+"a5 c #000000",
+"aZ c #797979",
+"aM c #000000",
+"ac c #020202",
+"aH c #030303",
+"#9 c #0a0a0a",
+"#i c #0e0e0e",
+"## c #1f1f1f",
+".q c #202020",
+"aB c #2b2b2b",
+"al c #2e2e2e",
+".j c #303030",
+"aw c #313131",
+"ag c #3b3b3b",
+"aL c #3c3c3c",
+"aj c #414141",
+".8 c #434343",
+"ai c #444444",
+"aa c #454545",
+".Y c #464646",
+"a# c #474747",
+"#5 c #484848",
+"a. c #494949",
+".6 c #4a4a4a",
+".Z c #4b4b4b",
+".D c #4c4c4c",
+"#f c #4d4d4d",
+"#p c #4e4e4e",
+".5 c #4f4f4f",
+".0 c #505050",
+".4 c #515151",
+".1 c #525252",
+"#c c #535353",
+"#r c #575757",
+".W c #5b5b5b",
+".S c #5e5e5e",
+"#2 c #5f5f5f",
+".v c #616161",
+".p c #676767",
+"#l c #6d6d6d",
+".k c #737373",
+".I c #757575",
+"aK c #777777",
+"aI c #7a7a7a",
+"aA c #909090",
+"#Z c #939393",
+"ax c #999999",
+"aJ c #9a9a9a",
+"#z c #9b9b9b",
+".o c #9d9d9d",
+".l c #a1a1a1",
+"#W c #a5a5a5",
+".C c #a7a7a7",
+"#u c #a8a8a8",
+"#h c #ababab",
+".n c #b2b2b2",
+".m c #b4b4b4",
+"az c #b6b6b6",
+"ar c #b8b8b8",
+"#a c #b9b9b9",
+"#T c #bababa",
+"ay c #bbbbbb",
+".R c #bcbcbc",
+"ak c #bdbdbd",
+"#I c #bfbfbf",
+".B c #c1c1c1",
+".7 c #c2c2c2",
+"#C c #c5c5c5",
+"#L c #c6c6c6",
+"ao c #c7c7c7",
+"aq c #c8c8c8",
+".A c #c9c9c9",
+".w c #cacaca",
+"ab c #cbcbcb",
+".X c #cccccc",
+"ap c #cdcdcd",
+".z c #cecece",
+".x c #cfcfcf",
+".y c #d0d0d0",
+"#Y c #d1d1d1",
+".Q c #d2d2d2",
+".J c #d3d3d3",
+"#6 c #d4d4d4",
+"#b c #d6d6d6",
+"#S c #d7d7d7",
+"#v c #d8d8d8",
+"#3 c #d9d9d9",
+"ah c #dadada",
+".K c #dbdbdb",
+"#y c #dcdcdc",
+"#D c #dfdfdf",
+"#R c #e0e0e0",
+"#m c #e1e1e1",
+"#M c #e3e3e3",
+"#g c #e4e4e4",
+".P c #e5e5e5",
+"#q c #e6e6e6",
+".L c #e7e7e7",
+"#4 c #e9e9e9",
+"#Q c #eaeaea",
+"#N c #ececec",
+"#H c #ededed",
+"#w c #eeeeee",
+".M c #efefef",
+"#P c #f0f0f0",
+".O c #f1f1f1",
+"#G c #f2f2f2",
+".N c #f3f3f3",
+"#O c #f4f4f4",
+"#E c #f5f5f5",
+"#X c #f6f6f6",
+"#F c #f7f7f7",
+"#x c #f8f8f8",
+"#o c #f9f9f9",
+".3 c #fafafa",
+".2 c #fbfbfb",
+"#e c #fcfcfc",
+"#d c #fdfdfd",
+"#n c #fefefe",
+"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt",
+"QtQtQtQtQtQt.#.a.b.c.d.e.f.gQtQtQtQtQtQtQtQtQtQt",
+"QtQtQtQt.h.i.j.k.l.m.n.o.p.q.r.sQtQtQtQtQtQtQtQt",
+"QtQtQt.t.u.v.m.w.x.y.z.A.B.C.D.E.FQtQtQtQtQtQtQt",
+"QtQt.G.H.I.w.J.K.L.M.N.O.P.Q.R.S.T.UQtQtQtQtQtQt",
+"QtQt.V.W.X.Y.Z.0.1.2.3.4.0.5.6.7.8.9QtQtQtQtQtQt",
+"Qt#.###a#b.D.1.1#c#d#e.1.4.5#f#g#h#i#jQtQtQtQtQt",
+"Qt#k#l.Q#m.0.1#d#n#n#d#e#o.0#p#q.K#r#sQtQtQtQtQt",
+"Qt#t#u#v#w.4.1#e#n#n#d.2#x.0#p#q#y#z#AQtQtQtQtQt",
+"Qt#B#C#D.M#E#x.2#d#d#e.3#F#G#H.P.K#I#JQtQtQtQtQt",
+"Qt#K#L#M#N#G#E#x.3.3.3#F#O#P#Q#R#S#T#UQtQtQtQtQt",
+"Qt#V#W#m.L#p.5#O#X#X#E.N.M#f.Z.K#Y#Z#0QtQtQtQtQt",
+"Qt#1#2#3#m.Z#f#w.M.M#w#H#4.Z#5#6.w.D#7QtQtQtQtQt",
+"Qt#8#9.m#v#5.6.Z.Z#q.L.6a.a#aaab.lacadQtQtQtQtQt",
+"Qtaeafag.Xaaaaa##5ah.Ka#.YaiajakalamQtQtQtQtQtQt",
+"QtQtan#U.4.7aoab.Xapababaq.7araaasatQtQtQtQtQtQt",
+"QtQtaeauavawaxayak.R.R.RazaAaBasaCaDaEQtQtQtQtQt",
+"QtQtQtaeaFaGaHajaIaJaJaKaLaMamaFaNaOaPaNaQQtQtQt",
+"QtQtQtQtQtaead#7aRasasaR#7adaSaeaeaTaUaVaCaSQtQt",
+"QtQtQtQtQtQtQtaeaeaeaeaeaeaeQtQtaeaWaXaYaDaVaeQt",
+"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtaeaPaZa0aPa1ae",
+"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtaeaea2aXa3a1ae",
+"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtaeaea4a5a6ae",
+"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtaeaeaeQtQt"};
diff --git a/ltt/branches/poly/lttv/modules/gui/histogram/stock_zoom_in_24.xpm b/ltt/branches/poly/lttv/modules/gui/histogram/stock_zoom_in_24.xpm
new file mode 100644 (file)
index 0000000..a23a444
--- /dev/null
@@ -0,0 +1,169 @@
+/* XPM */
+static char *stock_zoom_in_24[]={
+"24 24 142 2",
+"Qt c None",
+"#V c #000000",
+"ae c #010101",
+"#O c #020202",
+"#9 c #030303",
+"#J c #050505",
+"#v c #060606",
+"#n c #090909",
+"#P c #0a0a0a",
+"#K c #0b0b0b",
+"#W c #0c0c0c",
+"#e c #0e0e0e",
+".5 c #0f0f0f",
+".R c #101010",
+"#w c #111111",
+"#f c #121212",
+".C c #131313",
+"#o c #141414",
+"#g c #1b1b1b",
+".p c #1c1c1c",
+".6 c #1f1f1f",
+".o c #202020",
+".T c #212121",
+".F c #222222",
+".D c #232323",
+".S c #242424",
+".d c #262626",
+".s c #272727",
+".c c #292929",
+"ad c #2b2b2b",
+".b c #2d2d2d",
+".g c #2e2e2e",
+".h c #303030",
+"a. c #313131",
+".a c #343434",
+".e c #353535",
+".q c #373737",
+"al c #3a3a3a",
+"#1 c #3b3b3b",
+"ai c #3c3c3c",
+"#Y c #3f3f3f",
+".r c #404040",
+"#F c #414141",
+"#A c #424242",
+".4 c #434343",
+"#z c #444444",
+"## c #454545",
+".# c #494949",
+".B c #4c4c4c",
+".E c #4f4f4f",
+"#5 c #515151",
+"#m c #575757",
+".U c #5b5b5b",
+".f c #5d5d5d",
+".Q c #5e5e5e",
+"#Q c #5f5f5f",
+".t c #616161",
+".n c #676767",
+"aj c #686868",
+"#h c #6d6d6d",
+".i c #737373",
+".G c #757575",
+"ah c #777777",
+"ak c #797979",
+"af c #7a7a7a",
+"ac c #909090",
+"#N c #939393",
+"a# c #999999",
+"ag c #9a9a9a",
+"#u c #9b9b9b",
+".m c #9d9d9d",
+".j c #a1a1a1",
+"#L c #a5a5a5",
+".A c #a7a7a7",
+"#p c #a8a8a8",
+"#d c #ababab",
+".l c #b2b2b2",
+".k c #b4b4b4",
+"ab c #b6b6b6",
+"#8 c #b8b8b8",
+".7 c #b9b9b9",
+"#I c #bababa",
+"aa c #bbbbbb",
+".P c #bcbcbc",
+"#4 c #bdbdbd",
+"#C c #bfbfbf",
+".z c #c1c1c1",
+".3 c #c2c2c2",
+"#x c #c5c5c5",
+"#D c #c6c6c6",
+"#6 c #c7c7c7",
+"#3 c #c8c8c8",
+".y c #c9c9c9",
+".u c #cacaca",
+"#0 c #cbcbcb",
+".V c #cccccc",
+"#7 c #cdcdcd",
+".x c #cecece",
+".v c #cfcfcf",
+".w c #d0d0d0",
+"#M c #d1d1d1",
+".O c #d2d2d2",
+".H c #d3d3d3",
+"#U c #d4d4d4",
+"#2 c #d5d5d5",
+".8 c #d6d6d6",
+".W c #d7d7d7",
+"#q c #d8d8d8",
+"#R c #d9d9d9",
+"#Z c #dadada",
+".I c #dbdbdb",
+"#t c #dcdcdc",
+"#y c #dfdfdf",
+"#H c #e0e0e0",
+".2 c #e1e1e1",
+"#X c #e2e2e2",
+"#E c #e3e3e3",
+"#c c #e4e4e4",
+".N c #e5e5e5",
+"#l c #e6e6e6",
+".J c #e7e7e7",
+"#T c #e9e9e9",
+"#G c #eaeaea",
+"#S c #ebebeb",
+"#b c #ececec",
+"#B c #ededed",
+"#k c #eeeeee",
+".K c #efefef",
+".1 c #f0f0f0",
+".M c #f1f1f1",
+"#a c #f2f2f2",
+".L c #f3f3f3",
+"#s c #f4f4f4",
+".X c #f5f5f5",
+"#r c #f6f6f6",
+".0 c #f8f8f8",
+".9 c #f9f9f9",
+".Y c #fafafa",
+".Z c #fbfbfb",
+"#j c #fcfcfc",
+"#. c #fdfdfd",
+"#i c #fefefe",
+"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt",
+"QtQtQtQtQtQt.#.a.b.c.d.d.d.eQtQtQtQtQtQtQtQtQtQt",
+"QtQtQtQt.f.g.h.i.j.k.l.m.n.o.p.qQtQtQtQtQtQtQtQt",
+"QtQtQt.r.s.t.k.u.v.w.x.y.z.A.B.C.DQtQtQtQtQtQtQt",
+"QtQt.E.F.G.u.H.I.J.K.L.M.N.O.P.Q.R.SQtQtQtQtQtQt",
+"QtQt.T.U.V.W.N.X.Y.Z.Y.0.X.1.2.3.4.5QtQtQtQtQtQt",
+"Qt.h.6.7.8.J.9.Z#.####.Z.0#a#b#c#d#e#fQtQtQtQtQt",
+"Qt#g#h.O.2.X.Y#.#i#####j.9.X#k#l.I#m#nQtQtQtQtQt",
+"Qt#o#p#q#k#r.9#j#i####.Z.0#s#k#l#t#u#vQtQtQtQtQt",
+"Qt#w#x#y.K.X#z#z#######z.4#A#B.N.I#C#vQtQtQtQtQt",
+"Qt#e#D#E#b#a.4#z#z#z#z.4#A#F#G#H.W#I#JQtQtQtQtQt",
+"Qt#K#L.2.J#B.M#s#r.4.4.L.K#b#c.I#M#N#OQtQtQtQtQt",
+"Qt#P#Q#R.2#l#S#k.K#F#F#B#T#c.I#U.u.B#VQtQtQtQtQt",
+"Qt#W#P.k#q#t#X.N#l#Y#Y#E#y#Z#U#0.j#O#VQtQtQtQtQt",
+"Qt#V#v#1.V.O#U#Z.I#Z.I#q#2.w#3#4.g#VQtQtQtQtQtQt",
+"QtQt#J#J#5.3#6#0.V#7#0#0#3.3#8###V#VQtQtQtQtQtQt",
+"QtQt#V#9#9a.a#aa#4.P.P.Pabacad#V#V#V#VQtQtQtQtQt",
+"QtQtQt#V#Vae#9#Fafagagahai#V#V#V#V#V#V#V#VQtQtQt",
+"QtQtQtQtQt#V#V#V#V#V#V#V#V#V#V#V#V.o.o#V#V#VQtQt",
+"QtQtQtQtQtQtQt#V#V#V#V#V#V#VQtQt#V#Vaj.a#V#V#VQt",
+"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt#V#Vakal#V#V#V",
+"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt#V#V#Vaj.6#V#V",
+"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt#V#V#V#V#V#V",
+"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt#V#V#VQtQt"};
diff --git a/ltt/branches/poly/lttv/modules/gui/histogram/stock_zoom_out_24.xpm b/ltt/branches/poly/lttv/modules/gui/histogram/stock_zoom_out_24.xpm
new file mode 100644 (file)
index 0000000..6112199
--- /dev/null
@@ -0,0 +1,207 @@
+/* XPM */
+static char *stock_zoom_out_24[]={
+"24 24 180 2",
+"Qt c None",
+"#8 c #000000",
+"aw c #000000",
+"ae c #050505",
+".U c #242424",
+".s c #373737",
+".G c #4f4f4f",
+".h c #5d5d5d",
+"aJ c #000000",
+"aX c #000000",
+"ak c #000000",
+"aH c #000000",
+"#7 c #000000",
+"al c #030303",
+"#1 c #0c0c0c",
+"#i c #121212",
+".F c #232323",
+".8 c #303030",
+".g c #353535",
+".t c #404040",
+".# c #494949",
+"av c #000000",
+"#0 c #000000",
+"#p c #090909",
+"#U c #0a0a0a",
+"#j c #1b1b1b",
+".f c #262626",
+".a c #343434",
+"ad c #000000",
+"ax c #010101",
+"#9 c #060606",
+".7 c #0f0f0f",
+".r c #1c1c1c",
+".V c #212121",
+".i c #2e2e2e",
+"aI c #000000",
+"#T c #020202",
+"#x c #060606",
+"#P c #0b0b0b",
+"#q c #141414",
+".e c #262626",
+".b c #2d2d2d",
+"aE c #000000",
+"aV c #000000",
+"aN c #000000",
+"aF c #000000",
+"at c #000000",
+"au c #000000",
+"aG c #000000",
+"aK c #202020",
+"aS c #000000",
+"aL c #202020",
+"aM c #000000",
+"aP c #343434",
+"aT c #000000",
+"aj c #000000",
+"am c #030303",
+"#O c #050505",
+"#G c #060606",
+"#H c #0e0e0e",
+".T c #101010",
+"#y c #111111",
+".E c #131313",
+"aU c #1f1f1f",
+".H c #222222",
+".d c #262626",
+".u c #272727",
+".c c #292929",
+"aO c #686868",
+"aR c #3a3a3a",
+"aW c #000000",
+"aQ c #797979",
+"aD c #000000",
+"#6 c #020202",
+"ay c #030303",
+"#2 c #0a0a0a",
+"#h c #0e0e0e",
+".9 c #1f1f1f",
+".q c #202020",
+"as c #2b2b2b",
+"ac c #2e2e2e",
+".j c #303030",
+"an c #313131",
+"a. c #3b3b3b",
+"aC c #3c3c3c",
+"#K c #414141",
+"#D c #424242",
+".6 c #434343",
+"#B c #444444",
+"#C c #454545",
+".D c #4c4c4c",
+"af c #515151",
+"#o c #575757",
+".W c #5b5b5b",
+".S c #5e5e5e",
+"#V c #5f5f5f",
+".v c #616161",
+".p c #676767",
+"#k c #6d6d6d",
+".k c #737373",
+".I c #757575",
+"aB c #777777",
+"az c #7a7a7a",
+"ar c #909090",
+"#S c #939393",
+"ao c #999999",
+"aA c #9a9a9a",
+"#w c #9b9b9b",
+".o c #9d9d9d",
+".l c #a1a1a1",
+"#Q c #a5a5a5",
+".C c #a7a7a7",
+"#r c #a8a8a8",
+"#g c #ababab",
+".n c #b2b2b2",
+".m c #b4b4b4",
+"aq c #b6b6b6",
+"ai c #b8b8b8",
+"#. c #b9b9b9",
+"#N c #bababa",
+"ap c #bbbbbb",
+".R c #bcbcbc",
+"ab c #bdbdbd",
+"#F c #bfbfbf",
+".B c #c1c1c1",
+".5 c #c2c2c2",
+"#z c #c5c5c5",
+"#I c #c6c6c6",
+"ag c #c7c7c7",
+"aa c #c8c8c8",
+".A c #c9c9c9",
+".w c #cacaca",
+"#5 c #cbcbcb",
+".X c #cccccc",
+"ah c #cdcdcd",
+".z c #cecece",
+".x c #cfcfcf",
+".y c #d0d0d0",
+"#R c #d1d1d1",
+".Q c #d2d2d2",
+".J c #d3d3d3",
+"#Z c #d4d4d4",
+"a# c #d5d5d5",
+"## c #d6d6d6",
+".Y c #d7d7d7",
+"#s c #d8d8d8",
+"#W c #d9d9d9",
+"#4 c #dadada",
+".K c #dbdbdb",
+"#v c #dcdcdc",
+"#A c #dfdfdf",
+"#M c #e0e0e0",
+".4 c #e1e1e1",
+"#3 c #e2e2e2",
+"#J c #e3e3e3",
+"#f c #e4e4e4",
+".P c #e5e5e5",
+"#n c #e6e6e6",
+".L c #e7e7e7",
+"#Y c #e9e9e9",
+"#L c #eaeaea",
+"#X c #ebebeb",
+"#e c #ececec",
+"#E c #ededed",
+"#m c #eeeeee",
+".M c #efefef",
+".3 c #f0f0f0",
+".O c #f1f1f1",
+"#d c #f2f2f2",
+".N c #f3f3f3",
+"#u c #f4f4f4",
+".Z c #f5f5f5",
+"#t c #f6f6f6",
+".2 c #f8f8f8",
+"#a c #f9f9f9",
+".0 c #fafafa",
+".1 c #fbfbfb",
+"#c c #fcfcfc",
+"#b c #fdfdfd",
+"#l c #fefefe",
+"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt",
+"QtQtQtQtQtQt.#.a.b.c.d.e.f.gQtQtQtQtQtQtQtQtQtQt",
+"QtQtQtQt.h.i.j.k.l.m.n.o.p.q.r.sQtQtQtQtQtQtQtQt",
+"QtQtQt.t.u.v.m.w.x.y.z.A.B.C.D.E.FQtQtQtQtQtQtQt",
+"QtQt.G.H.I.w.J.K.L.M.N.O.P.Q.R.S.T.UQtQtQtQtQtQt",
+"QtQt.V.W.X.Y.P.Z.0.1.0.2.Z.3.4.5.6.7QtQtQtQtQtQt",
+"Qt.8.9#.##.L#a.1#b#b#c.1.2#d#e#f#g#h#iQtQtQtQtQt",
+"Qt#j#k.Q.4.Z.0#b#l#l#b#c#a.Z#m#n.K#o#pQtQtQtQtQt",
+"Qt#q#r#s#m#t#a#c#l#l#b.1.2#u#m#n#v#w#xQtQtQtQtQt",
+"Qt#y#z#A.M.Z#B#B#C#C#C#B.6#D#E.P.K#F#GQtQtQtQtQt",
+"Qt#H#I#J#e#d.6#B#B#B#B.6#D#K#L#M.Y#N#OQtQtQtQtQt",
+"Qt#P#Q.4.L#E.O#u#t#t.Z.N.M#e#f.K#R#S#TQtQtQtQtQt",
+"Qt#U#V#W.4#n#X#m.M.M#m#E#Y#f.K#Z.w.D#0QtQtQtQtQt",
+"Qt#1#2.m#s#v#3.P#n#n.L#J#A#4#Z#5.l#6#7QtQtQtQtQt",
+"Qt#8#9a..X.Q#Z#4.K#4.K#sa#.yaaabacadQtQtQtQtQtQt",
+"QtQtae#Oaf.5ag#5.Xah#5#5aa.5ai#CajakQtQtQtQtQtQt",
+"QtQt#8alamanaoapab.R.R.RaqarasajatauavQtQtQtQtQt",
+"QtQtQt#8awaxay#KazaAaAaBaCaDadawaEaFaGaEaHQtQtQt",
+"QtQtQtQtQt#8#7#0aIajajaI#0#7aJ#8#8aKaLaMataJQtQt",
+"QtQtQtQtQtQtQt#8#8#8#8#8#8#8QtQt#8aNaOaPauaM#8Qt",
+"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt#8aGaQaRaGaS#8",
+"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt#8#8aTaOaUaS#8",
+"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt#8#8aVaWaX#8",
+"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt#8#8#8QtQt"};
This page took 0.101353 seconds and 4 git commands to generate.