From: compudj Date: Tue, 27 Jan 2004 21:19:02 +0000 (+0000) Subject: part 7 X-Git-Tag: v0.12.20~3085 X-Git-Url: http://git.lttng.org./?a=commitdiff_plain;h=b9f1fde9d713ca417cdc67737c2ba75f6d86d0cd;p=lttv.git part 7 git-svn-id: http://ltt.polymtl.ca/svn@404 04897980-b3bd-0310-b5e0-8ef037075253 --- diff --git a/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/CFV-private.h b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/CFV-private.h new file mode 100644 index 00000000..2903a281 --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/CFV-private.h @@ -0,0 +1,28 @@ +#ifndef _CFV_PRIVATE_H +#define _CFV_PRIVATE_H + + + +struct _ControlFlowData { + + GtkWidget *scrolled_window; + MainWindow *mw; + + ProcessList *process_list; + Drawing_t *drawing; + + GtkWidget *h_paned; + + GtkAdjustment *v_adjust ; + + /* Shown events information */ + TimeWindow time_window; + LttTime current_time; + + //guint currently_Selected_Event ; + guint number_of_process; + +} ; + + +#endif //_CFV_PRIVATE_H diff --git a/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/CFV.c b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/CFV.c new file mode 100644 index 00000000..ac371adc --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/CFV.c @@ -0,0 +1,173 @@ + +#include +#include +#include + +#include "CFV.h" +#include "Drawing.h" +#include "Process_List.h" +#include "Event_Hooks.h" +#include "CFV-private.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) + +extern GSList *g_control_flow_data_list; + +/***************************************************************************** + * Control Flow Viewer class implementation * + *****************************************************************************/ +/** + * 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. + */ +ControlFlowData * +guicontrolflow(void) +{ + GtkWidget *process_list_widget, *drawing_widget; + + ControlFlowData* control_flow_data = g_new(ControlFlowData,1) ; + + /* Create the drawing */ + control_flow_data->drawing = drawing_construct(control_flow_data); + + drawing_widget = + drawing_get_widget(control_flow_data->drawing); + + control_flow_data->number_of_process = 0; + + /* Create the Process list */ + control_flow_data->process_list = processlist_construct(); + + process_list_widget = + processlist_get_widget(control_flow_data->process_list); + + //control_flow_data->Inside_HBox_V = gtk_hbox_new(0, 0); + control_flow_data->h_paned = gtk_hpaned_new(); + + gtk_paned_pack1(GTK_PANED(control_flow_data->h_paned), process_list_widget, FALSE, TRUE); + gtk_paned_pack2(GTK_PANED(control_flow_data->h_paned), drawing_widget, TRUE, TRUE); + + 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 */ + + control_flow_data->scrolled_window = + gtk_scrolled_window_new (NULL, + control_flow_data->v_adjust); + + gtk_scrolled_window_set_policy( + GTK_SCROLLED_WINDOW(control_flow_data->scrolled_window) , + GTK_POLICY_NEVER, + GTK_POLICY_AUTOMATIC); + + gtk_scrolled_window_add_with_viewport( + GTK_SCROLLED_WINDOW(control_flow_data->scrolled_window), + control_flow_data->h_paned); + + /* Set the size of the drawing area */ + //drawing_Resize(drawing, h, w); + + /* Get trace statistics */ + //control_flow_data->Trace_Statistics = get_trace_statistics(Trace); + + + gtk_widget_show(drawing_widget); + gtk_widget_show(process_list_widget); + gtk_widget_show(control_flow_data->h_paned); + gtk_widget_show(control_flow_data->scrolled_window); + + g_object_set_data_full( + G_OBJECT(control_flow_data->scrolled_window), + "control_flow_data", + control_flow_data, + (GDestroyNotify)guicontrolflow_destructor); + + g_object_set_data( + G_OBJECT(drawing_widget), + "control_flow_data", + control_flow_data); + + g_control_flow_data_list = g_slist_append( + g_control_flow_data_list, + control_flow_data); + + //WARNING : The widget must be + //inserted in the main window before the drawing area + //can be configured (and this must happend bedore sending + //data) + + return control_flow_data; + +} + +/* Destroys widget also */ +void +guicontrolflow_destructor_full(ControlFlowData *control_flow_data) +{ + g_info("CFV.c : guicontrolflow_destructor_full, %p", control_flow_data); + /* May already have been done by GTK window closing */ + if(GTK_IS_WIDGET(control_flow_data->scrolled_window)) + gtk_widget_destroy(control_flow_data->scrolled_window); + //control_flow_data->mw = NULL; + //FIXME guicontrolflow_destructor(control_flow_data); +} + +/* When this destructor is called, the widgets are already disconnected */ +void +guicontrolflow_destructor(ControlFlowData *control_flow_data) +{ + guint index; + + g_info("CFV.c : guicontrolflow_destructor, %p", control_flow_data); + g_info("%p, %p, %p", update_time_window_hook, control_flow_data, control_flow_data->mw); + if(GTK_IS_WIDGET(control_flow_data->scrolled_window)) + g_info("widget still exists"); + + /* Process List is removed with it's widget */ + //ProcessList_destroy(control_flow_data->process_list); + if(control_flow_data->mw != NULL) + { + unreg_update_time_window(update_time_window_hook, + control_flow_data, + control_flow_data->mw); + + unreg_update_current_time(update_current_time_hook, + control_flow_data, + control_flow_data->mw); + } + g_info("CFV.c : guicontrolflow_destructor, %p", control_flow_data); + g_slist_remove(g_control_flow_data_list,control_flow_data); + g_free(control_flow_data); +} + +GtkWidget *guicontrolflow_get_widget(ControlFlowData *control_flow_data) +{ + return control_flow_data->scrolled_window ; +} + +ProcessList *guicontrolflow_get_process_list + (ControlFlowData *control_flow_data) +{ + return control_flow_data->process_list ; +} + +TimeWindow *guicontrolflow_get_time_window(ControlFlowData *control_flow_data) +{ + return &control_flow_data->time_window; +} +LttTime *guicontrolflow_get_current_time(ControlFlowData *control_flow_data) +{ + return &control_flow_data->current_time; +} + + diff --git a/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/CFV.h b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/CFV.h new file mode 100644 index 00000000..208cbf7e --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/CFV.h @@ -0,0 +1,23 @@ +#ifndef _CFV_H +#define _CFV_H + +#include +#include +#include +#include "Process_List.h" + +typedef struct _ControlFlowData ControlFlowData; + +/* Control Flow Data constructor */ +ControlFlowData *guicontrolflow(void); +void +guicontrolflow_destructor_full(ControlFlowData *control_flow_data); +void +guicontrolflow_destructor(ControlFlowData *control_flow_data); +GtkWidget *guicontrolflow_get_widget(ControlFlowData *control_flow_data); +ProcessList *guicontrolflow_get_process_list(ControlFlowData *control_flow_data); +TimeWindow *guicontrolflow_get_time_window(ControlFlowData *control_flow_data); +LttTime *guicontrolflow_get_current_time(ControlFlowData *control_flow_data); + + +#endif // _CFV_H diff --git a/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Draw_Item.c b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Draw_Item.c new file mode 100644 index 00000000..7c929c82 --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Draw_Item.c @@ -0,0 +1,345 @@ +/****************************************************************************** + * Draw_Item.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 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "Draw_Item.h" + + +#define MAX_PATH_LEN 256 + +/* drawing hook functions */ +gboolean draw_text( void *hook_data, void *call_data) +{ + PropertiesText *Properties = (PropertiesText*)hook_data; + DrawContext *Draw_Context = (DrawContext*)call_data; + + PangoContext *context; + PangoLayout *layout; + PangoAttribute *attribute; + PangoFontDescription *FontDesc;// = pango_font_description_new(); + gint Font_Size; + PangoRectangle ink_rect; + + layout = Draw_Context->pango_layout; + + context = pango_layout_get_context(layout); + FontDesc = pango_context_get_font_description(context); + + pango_font_description_set_size(FontDesc, 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); + switch(Properties->position) { + case OVER: + gdk_draw_layout_with_colors(Draw_Context->drawable, + Draw_Context->gc, + Draw_Context->current->modify_over->x, + Draw_Context->current->modify_over->y, + layout, Properties->foreground, Properties->background); + Draw_Context->current->modify_over->x += ink_rect.width; + + break; + case MIDDLE: + gdk_draw_layout_with_colors(Draw_Context->drawable, + Draw_Context->gc, + Draw_Context->current->modify_middle->x, + Draw_Context->current->modify_middle->y, + layout, Properties->foreground, Properties->background); + Draw_Context->current->modify_middle->x += ink_rect.width; + break; + case UNDER: + gdk_draw_layout_with_colors(Draw_Context->drawable, + Draw_Context->gc, + Draw_Context->current->modify_under->x, + Draw_Context->current->modify_under->y, + layout, Properties->foreground, Properties->background); + Draw_Context->current->modify_under->x += ink_rect.width; + break; + } + + return 0; +} + + +/* To speed up the process, search in already loaded icons list first. Only + * load it if not present. + */ +gboolean draw_icon( void *hook_data, void *call_data) +{ + PropertiesIcon *Properties = (PropertiesIcon*)hook_data; + DrawContext *Draw_Context = (DrawContext*)call_data; + + LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes()); + LttvAttributeValue value; + gchar icon_name[MAX_PATH_LEN] = "icons/"; + IconStruct *icon_info; + + strcat(icon_name, Properties->icon_name); + + g_assert(lttv_iattribute_find_by_path(attributes, icon_name, + LTTV_POINTER, &value)); + if(*(value.v_pointer) == NULL) + { + *(value.v_pointer) = icon_info = g_new(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); + } + + gdk_gc_set_clip_mask(Draw_Context->gc, icon_info->mask); + + switch(Properties->position) { + case OVER: + gdk_gc_set_clip_origin( + Draw_Context->gc, + Draw_Context->current->modify_over->x, + Draw_Context->current->modify_over->y); + gdk_draw_drawable(Draw_Context->drawable, + Draw_Context->gc, + icon_info->pixmap, + 0, 0, + Draw_Context->current->modify_over->x, + Draw_Context->current->modify_over->y, + Properties->width, Properties->height); + + Draw_Context->current->modify_over->x += Properties->width; + + break; + case MIDDLE: + gdk_gc_set_clip_origin( + Draw_Context->gc, + Draw_Context->current->modify_middle->x, + Draw_Context->current->modify_middle->y); + gdk_draw_drawable(Draw_Context->drawable, + Draw_Context->gc, + icon_info->pixmap, + 0, 0, + Draw_Context->current->modify_middle->x, + Draw_Context->current->modify_middle->y, + Properties->width, Properties->height); + + Draw_Context->current->modify_middle->x += Properties->width; + break; + case UNDER: + gdk_gc_set_clip_origin( + Draw_Context->gc, + Draw_Context->current->modify_under->x, + Draw_Context->current->modify_under->y); + gdk_draw_drawable(Draw_Context->drawable, + Draw_Context->gc, + icon_info->pixmap, + 0, 0, + Draw_Context->current->modify_under->x, + Draw_Context->current->modify_under->y, + Properties->width, Properties->height); + + Draw_Context->current->modify_under->x += Properties->width; + break; + } + + gdk_gc_set_clip_origin(Draw_Context->gc, 0, 0); + gdk_gc_set_clip_mask(Draw_Context->gc, NULL); + + return 0; +} + +gboolean draw_line( void *hook_data, void *call_data) +{ + PropertiesLine *Properties = (PropertiesLine*)hook_data; + DrawContext *Draw_Context = (DrawContext*)call_data; + //GdkGC *gc = gdk_gc_new(Draw_Context->drawable); + + //gdk_gc_set_foreground(Draw_Context->gc, Properties->color); + gdk_gc_set_rgb_fg_color(Draw_Context->gc, Properties->color); + //gdk_gc_set_foreground(gc, Properties->color); + gdk_gc_set_line_attributes( Draw_Context->gc, + Properties->line_width, + Properties->style, + GDK_CAP_BUTT, + GDK_JOIN_MITER); + + switch(Properties->position) { + case OVER: + drawing_draw_line( + NULL, Draw_Context->drawable, + Draw_Context->previous->over->x, + Draw_Context->previous->over->y, + Draw_Context->current->over->x, + Draw_Context->current->over->y, + Draw_Context->gc); + break; + case MIDDLE: + drawing_draw_line( + NULL, Draw_Context->drawable, + Draw_Context->previous->middle->x, + Draw_Context->previous->middle->y, + Draw_Context->current->middle->x, + Draw_Context->current->middle->y, + Draw_Context->gc); + break; + case UNDER: + drawing_draw_line( + NULL, Draw_Context->drawable, + Draw_Context->previous->under->x, + Draw_Context->previous->under->y, + Draw_Context->current->under->x, + Draw_Context->current->under->y, + Draw_Context->gc); + + break; + } + + //gdk_gc_unref(gc); + + return 0; +} + +gboolean draw_arc( void *hook_data, void *call_data) +{ + PropertiesArc *Properties = (PropertiesArc*)hook_data; + DrawContext *Draw_Context = (DrawContext*)call_data; + + //gdk_gc_set_foreground(Draw_Context->gc, Properties->color); + gdk_gc_set_rgb_fg_color(Draw_Context->gc, Properties->color); + + switch(Properties->position) { + case OVER: + gdk_draw_arc(Draw_Context->drawable, Draw_Context->gc, + Properties->filled, + Draw_Context->current->modify_over->x, + Draw_Context->current->modify_over->y, + Properties->size, Properties->size, 0, 360*64); + Draw_Context->current->modify_over->x += Properties->size; + break; + case MIDDLE: + gdk_draw_arc(Draw_Context->drawable, Draw_Context->gc, + Properties->filled, + Draw_Context->current->modify_middle->x, + Draw_Context->current->modify_middle->y, + Properties->size, Properties->size, 0, 360*64); + Draw_Context->current->modify_middle->x += Properties->size; + + break; + case UNDER: + gdk_draw_arc(Draw_Context->drawable, Draw_Context->gc, + Properties->filled, + Draw_Context->current->modify_under->x, + Draw_Context->current->modify_under->y, + Properties->size, Properties->size, 0, 360*64); + Draw_Context->current->modify_under->x += Properties->size; + + break; + } + + + return 0; +} + +gboolean draw_bg( void *hook_data, void *call_data) +{ + PropertiesBG *Properties = (PropertiesBG*)hook_data; + DrawContext *Draw_Context = (DrawContext*)call_data; + + //gdk_gc_set_foreground(Draw_Context->gc, Properties->color); + gdk_gc_set_rgb_fg_color(Draw_Context->gc, Properties->color); + + + gdk_draw_rectangle(Draw_Context->drawable, Draw_Context->gc, + TRUE, + Draw_Context->previous->over->x, + Draw_Context->previous->over->y, + Draw_Context->current->over->x - Draw_Context->previous->over->x, + Draw_Context->previous->under->y); + + return 0; +} + + diff --git a/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Draw_Item.h b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Draw_Item.h new file mode 100644 index 00000000..9f342052 --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Draw_Item.h @@ -0,0 +1,283 @@ +#ifndef _DRAW_ITEM_H +#define _DRAW_ITEM_H + +#include + +typedef struct _DrawContext DrawContext; +typedef struct _DrawInfo DrawInfo; +typedef struct _ItemInfo ItemInfo; + +typedef struct _IconStruct IconStruct; + +typedef struct _DrawOperation DrawOperation; + + +typedef struct _PropertiesText PropertiesText; +typedef struct _PropertiesIcon PropertiesIcon; +typedef struct _PropertiesLine PropertiesLine; +typedef struct _PropertiesArc PropertiesArc; +typedef struct _PropertiesBG PropertiesBG; + +typedef enum _DrawableItems DrawableItems; +enum _DrawableItems { + ITEM_TEXT, ITEM_ICON, ITEM_LINE, ITEM_POINT, ITEM_BACKGROUND +}; + + +typedef enum _RelPos { + OVER, MIDDLE, UNDER +} RelPos; + + +/* 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. + * + */ + + +struct _DrawContext { + GdkDrawable *drawable; + GdkGC *gc; + PangoLayout *pango_layout; + + DrawInfo *current; + DrawInfo *previous; +}; + +/* LttvExecutionState is accessible through the LttvTracefileState. Is has + * a pointer to the LttvProcessState which points to the top of stack + * execution state : LttvExecutionState *state. + * + * LttvExecutionState contains (useful here): + * LttvExecutionMode t, + * LttvExecutionSubmode n, + * LttvProcessStatus s + * + * + * LttvTraceState will be used in the case we need the string of the + * different processes, eventtype_names, syscall_names, trap_names, irq_names. + * + * LttvTracefileState also gives the cpu_name and, as it herits from + * LttvTracefileContext, it gives the LttEvent structure, which is needed + * to get facility name and event name. + */ +struct _DrawInfo { + ItemInfo *over; + ItemInfo *middle; + ItemInfo *under; + + ItemInfo *modify_over; + ItemInfo *modify_middle; + ItemInfo *modify_under; + LttvProcessStatus status; +}; + +struct _ItemInfo { + gint x, y; +}; + +/* + * Structure used to keep information about icons. + */ +struct _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 _DrawOperation { + DrawableItems item; + LttvHooks *hook; +}; + +/* + * 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 */ +}; + +/* + * 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 _PropertiesText { + GdkColor *foreground; + GdkColor *background; + gint size; + gchar *text; + RelPos position; +}; + + +struct _PropertiesIcon { + gchar *icon_name; + gint width; + gint height; + RelPos position; +}; + +struct _PropertiesLine { + GdkColor *color; + gint line_width; + GdkLineStyle style; + RelPos position; +}; + +struct _PropertiesArc { + GdkColor *color; + gint size; /* We force circle by width = height */ + gboolean filled; + RelPos position; +}; + +struct _PropertiesBG { + GdkColor *color; +}; + + + +void 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" + */ + +/* + * 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); + + +/* + * Functions to create Properties structures. + */ + +PropertiesText *properties_text_create( + GdkColor *foreground, + GdkColor *background, + gint size, + gchar *text, + RelPos position); + +PropertiesIcon *properties_icon_create( + gchar *icon_name, + gint width, + gint height, + RelPos position); + +PropertiesLine *properties_line_create( + GdkColor *color, + gint line_width, + GdkLineStyle style, + RelPos position); + +PropertiesArc *properties_arc_create( + GdkColor *color, + gint size, + gboolean filled, + RelPos position); + +PropertiesBG *properties_bg_create( + GdkColor *color); + + + + +/* + * Here follow the prototypes of the hook functions used to draw the + * different items. + */ + +gboolean draw_text( void *hook_data, void *call_data); +gboolean draw_icon( void *hook_data, void *call_data); +gboolean draw_line( void *hook_data, void *call_data); +gboolean draw_arc( void *hook_data, void *call_data); +gboolean draw_bg( void *hook_data, void *call_data); + + +#endif // _DRAW_ITEM_H diff --git a/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Drawing.c b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Drawing.c new file mode 100644 index 00000000..85d2efcb --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Drawing.c @@ -0,0 +1,640 @@ + +#include +#include + +#include +#include +#include + +#include "Drawing.h" +#include "CFV.h" +#include "CFV-private.h" +#include "Event_Hooks.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) + +/***************************************************************************** + * drawing functions * + *****************************************************************************/ + +//FIXME Colors will need to be dynamic. Graphic context part not done so far. +typedef enum +{ + RED, + GREEN, + BLUE, + WHITE, + BLACK + +} ControlFlowColors; + +/* Vector of unallocated colors */ +static GdkColor CF_Colors [] = +{ + { 0, 0xffff, 0x0000, 0x0000 }, // RED + { 0, 0x0000, 0xffff, 0x0000 }, // GREEN + { 0, 0x0000, 0x0000, 0xffff }, // BLUE + { 0, 0xffff, 0xffff, 0xffff }, // WHITE + { 0, 0x0000, 0x0000, 0x0000 } // BLACK +}; + + +/* Function responsible for updating the exposed area. + * It must call processTrace() to ask for this update. + * Note : this function cannot clear the background, because it may + * erase drawing already present (SAFETY). + */ +void drawing_data_request(Drawing_t *drawing, + GdkPixmap **pixmap, + gint x, gint y, + gint width, + gint height) +{ + if(width < 0) return ; + if(height < 0) return ; + ControlFlowData *control_flow_data = + (ControlFlowData*)g_object_get_data( + G_OBJECT( + drawing->drawing_area), + "control_flow_data"); + + LttTime start, end; + LttTime window_end = ltt_time_add(control_flow_data->time_window.time_width, + control_flow_data->time_window.start_time); + + g_critical("req : window_end : %u, %u", window_end.tv_sec, + window_end.tv_nsec); + + g_critical("req : time width : %u, %u", control_flow_data->time_window.time_width.tv_sec, + control_flow_data->time_window.time_width.tv_nsec); + + g_critical("x is : %i, x+width is : %i", x, x+width); + + convert_pixels_to_time(drawing->drawing_area->allocation.width, x, + &control_flow_data->time_window.start_time, + &window_end, + &start); + + convert_pixels_to_time(drawing->drawing_area->allocation.width, x + width, + &control_flow_data->time_window.start_time, + &window_end, + &end); + + LttvTracesetContext * tsc = + get_traceset_context(control_flow_data->mw); + + //send_test_process( + //guicontrolflow_get_process_list(drawing->control_flow_data), + //drawing); + //send_test_drawing( + //guicontrolflow_get_process_list(drawing->control_flow_data), + //drawing, *pixmap, x, y, width, height); + + // Let's call processTrace() !! + EventRequest event_request; // Variable freed at the end of the function. + event_request.control_flow_data = control_flow_data; + event_request.time_begin = start; + event_request.time_end = end; + event_request.x_begin = x; + event_request.x_end = x+width; + + g_critical("req : start : %u, %u", event_request.time_begin.tv_sec, + event_request.time_begin.tv_nsec); + + g_critical("req : end : %u, %u", event_request.time_end.tv_sec, + event_request.time_end.tv_nsec); + + LttvHooks *event = lttv_hooks_new(); + LttvHooks *after_event = lttv_hooks_new(); + LttvHooks *after_traceset = lttv_hooks_new(); + lttv_hooks_add(after_traceset, after_data_request, &event_request); + lttv_hooks_add(event, draw_event_hook, &event_request); + //Modified by xiangxiu: state update hooks are added by the main window + //state_add_event_hooks_api(control_flow_data->mw); + lttv_hooks_add(after_event, draw_after_hook, &event_request); + + lttv_process_traceset_seek_time(tsc, start); + // FIXME : would like to place the after_traceset hook after the traceset, + // but the traceset context state is not valid anymore. + lttv_traceset_context_add_hooks(tsc, + // NULL, after_traceset, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, after_traceset, NULL, event, after_event); + lttv_process_traceset(tsc, end, G_MAXULONG); + //after_data_request((void*)&event_request,(void*)tsc); + lttv_traceset_context_remove_hooks(tsc, + //NULL, after_traceset, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, after_traceset, NULL, event, after_event); + //Modified by xiangxiu: state update hooks are removed by the main window + //state_remove_event_hooks_api(control_flow_data->mw); + + lttv_hooks_destroy(after_traceset); + lttv_hooks_destroy(event); + lttv_hooks_destroy(after_event); + + +} + +/* 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. + */ +static gboolean +configure_event( GtkWidget *widget, GdkEventConfigure *event, + gpointer user_data) +{ + Drawing_t *drawing = (Drawing_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. + */ + get_time_window(drawing->control_flow_data->mw, + &drawing->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_critical("drawing configure event"); + g_critical("New draw size : %i by %i",widget->allocation.width, widget->allocation.height); + + + if (drawing->pixmap) + gdk_pixmap_unref(drawing->pixmap); + + /* If no old pixmap present */ + //if(drawing->pixmap == NULL) + { + drawing->pixmap = gdk_pixmap_new( + widget->window, + widget->allocation.width + SAFETY, + widget->allocation.height + SAFETY, + //ProcessList_get_height + // (GuiControlFlow_get_process_list(drawing->control_flow_data)), + -1); + drawing->width = widget->allocation.width; + drawing->height = widget->allocation.height; + + + // Clear the image + gdk_draw_rectangle (drawing->pixmap, + widget->style->white_gc, + TRUE, + 0, 0, + widget->allocation.width+SAFETY, + widget->allocation.height+SAFETY); + + //g_info("init data request"); + + + /* Initial data request */ + // Do not need to ask for data of 1 pixel : not synchronized with + // main window time at this moment. + drawing_data_request(drawing, &drawing->pixmap, 0, 0, + widget->allocation.width, + widget->allocation.height); + + drawing->width = widget->allocation.width; + drawing->height = widget->allocation.height; + + return TRUE; + + + + } +#ifdef NOTUSE +// /* Draw empty background */ +// gdk_draw_rectangle (pixmap, +// widget->style->black_gc, +// TRUE, +// 0, 0, +// widget->allocation.width, +// widget->allocation.height); + + /* Copy old data to new pixmap */ + gdk_draw_drawable (pixmap, + widget->style->white_gc, + drawing->pixmap, + 0, 0, + 0, 0, + -1, -1); + + if (drawing->pixmap) + gdk_pixmap_unref(drawing->pixmap); + + drawing->pixmap = pixmap; + + // Clear the bottom part of the image (SAFETY) + gdk_draw_rectangle (pixmap, + widget->style->white_gc, + TRUE, + 0, drawing->height+SAFETY, + drawing->width+SAFETY, // do not overlap + (widget->allocation.height) - drawing->height); + + // Clear the right part of the image (SAFETY) + gdk_draw_rectangle (pixmap, + widget->style->white_gc, + TRUE, + drawing->width+SAFETY, 0, + (widget->allocation.width) - drawing->width, // do not overlap + drawing->height+SAFETY); + + /* Clear the backgound for data request, but not SAFETY */ + gdk_draw_rectangle (pixmap, + drawing->drawing_area->style->white_gc, + TRUE, + drawing->width + SAFETY, 0, + widget->allocation.width - drawing->width, // do not overlap + widget->allocation.height+SAFETY); + + /* Request data for missing space */ + g_info("missing data request"); + drawing_data_request(drawing, &pixmap, drawing->width, 0, + widget->allocation.width - drawing->width, + widget->allocation.height); + + drawing->width = widget->allocation.width; + drawing->height = widget->allocation.height; + + return TRUE; +#endif //NOTUSE +} + + +/* Redraw the screen from the backing pixmap */ +static gboolean +expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data ) +{ + Drawing_t *drawing = (Drawing_t*)user_data; + ControlFlowData *control_flow_data = + (ControlFlowData*)g_object_get_data( + G_OBJECT(widget), + "control_flow_data"); + + g_critical("drawing expose event"); + + guint x=0; + LttTime* current_time = + guicontrolflow_get_current_time(control_flow_data); + + LttTime window_end = ltt_time_add(control_flow_data->time_window.time_width, + control_flow_data->time_window.start_time); + + convert_time_to_pixels( + control_flow_data->time_window.start_time, + window_end, + *current_time, + widget->allocation.width, + &x); + + 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); + + if(x >= event->area.x && x <= event->area.x+event->area.width) + { + GdkGC *gc = gdk_gc_new(control_flow_data->drawing->pixmap); + gdk_gc_copy(gc, widget->style->black_gc); + + drawing_draw_line(NULL, widget->window, + x, event->area.y, + x, event->area.y+event->area.height, + gc); + gdk_gc_unref(gc); + } + return FALSE; +} + +/* mouse click */ +static gboolean +button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer user_data ) +{ + ControlFlowData *control_flow_data = + (ControlFlowData*)g_object_get_data( + G_OBJECT(widget), + "control_flow_data"); + Drawing_t *drawing = control_flow_data->drawing; + + + g_critical("click"); + if(event->button == 1) + { + LttTime time; + + LttTime window_end = ltt_time_add(control_flow_data->time_window.time_width, + control_flow_data->time_window.start_time); + + + /* left mouse button click */ + g_critical("x click is : %f", event->x); + + convert_pixels_to_time(widget->allocation.width, (guint)event->x, + &control_flow_data->time_window.start_time, + &window_end, + &time); + + set_current_time(control_flow_data->mw, &time); + + } + + return FALSE; +} + + + + +Drawing_t *drawing_construct(ControlFlowData *control_flow_data) +{ + Drawing_t *drawing = g_new(Drawing_t, 1); + + drawing->drawing_area = gtk_drawing_area_new (); + drawing->control_flow_data = control_flow_data; + + drawing->pango_layout = + gtk_widget_create_pango_layout(drawing->drawing_area, NULL); + + //gtk_widget_set_size_request(drawing->drawing_area->window, 50, 50); + g_object_set_data_full( + G_OBJECT(drawing->drawing_area), + "Link_drawing_Data", + drawing, + (GDestroyNotify)drawing_destroy); + + //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); + + gtk_widget_add_events(drawing->drawing_area, GDK_BUTTON_PRESS_MASK); + + g_signal_connect (G_OBJECT(drawing->drawing_area), + "configure_event", + G_CALLBACK (configure_event), + (gpointer)drawing); + + g_signal_connect (G_OBJECT(drawing->drawing_area), + "expose_event", + G_CALLBACK (expose_event), + (gpointer)drawing); + + g_signal_connect (G_OBJECT(drawing->drawing_area), + "button-press-event", + G_CALLBACK (button_press_event), + (gpointer)drawing); + + + return drawing; +} + +void drawing_destroy(Drawing_t *drawing) +{ + + // Do not unref here, Drawing_t destroyed by it's widget. + //g_object_unref( G_OBJECT(drawing->drawing_area)); + + g_free(drawing->pango_layout); + g_free(drawing); +} + +GtkWidget *drawing_get_widget(Drawing_t *drawing) +{ + return drawing->drawing_area; +} + +/* convert_pixels_to_time + * + * Convert from window pixel and time interval to an absolute time. + */ +void convert_pixels_to_time( + gint width, + guint x, + LttTime *window_time_begin, + LttTime *window_time_end, + LttTime *time) +{ + LttTime window_time_interval; + + window_time_interval = ltt_time_sub(*window_time_end, + *window_time_begin); + *time = ltt_time_mul(window_time_interval, (x/(float)width)); + *time = ltt_time_add(*window_time_begin, *time); +} + + + +void convert_time_to_pixels( + LttTime window_time_begin, + LttTime window_time_end, + LttTime time, + int width, + guint *x) +{ + LttTime window_time_interval; + float interval_float, time_float; + + window_time_interval = ltt_time_sub(window_time_end,window_time_begin); + + time = ltt_time_sub(time, window_time_begin); + + interval_float = ltt_time_to_double(window_time_interval); + time_float = ltt_time_to_double(time); + + *x = (guint)(time_float/interval_float * width); + +} + +void drawing_refresh ( Drawing_t *drawing, + guint x, guint y, + guint width, guint height) +{ + g_info("Drawing.c : drawing_refresh %u, %u, %u, %u", x, y, width, height); + GdkRectangle update_rect; + + gdk_draw_drawable( + drawing->drawing_area->window, + drawing->drawing_area-> + style->fg_gc[GTK_WIDGET_STATE (drawing->drawing_area)], + GDK_DRAWABLE(drawing->pixmap), + x, y, + x, y, + width, height); + + update_rect.x = 0 ; + update_rect.y = 0 ; + update_rect.width = drawing->width; + update_rect.height = drawing->height ; + gtk_widget_draw( drawing->drawing_area, &update_rect); + +} + + +void drawing_draw_line( Drawing_t *drawing, + GdkPixmap *pixmap, + guint x1, guint y1, + guint x2, guint y2, + GdkGC *GC) +{ + gdk_draw_line (pixmap, + GC, + x1, y1, x2, y2); +} + + + + +void drawing_resize(Drawing_t *drawing, guint h, guint w) +{ + drawing->height = h ; + drawing->width = w ; + + gtk_widget_set_size_request ( drawing->drawing_area, + drawing->width, + drawing->height); + + +} + + +/* Insert a square corresponding to a new process in the list */ +/* Applies to whole drawing->width */ +void drawing_insert_square(Drawing_t *drawing, + guint y, + guint height) +{ + //GdkRectangle update_rect; + + /* Allocate a new pixmap with new height */ + GdkPixmap *pixmap = gdk_pixmap_new(drawing->drawing_area->window, + drawing->width + SAFETY, + drawing->height + height + SAFETY, + -1); + + /* Copy the high region */ + gdk_draw_drawable (pixmap, + drawing->drawing_area->style->black_gc, + drawing->pixmap, + 0, 0, + 0, 0, + drawing->width + SAFETY, y); + + + + + /* add an empty square */ + gdk_draw_rectangle (pixmap, + drawing->drawing_area->style->white_gc, + TRUE, + 0, y, + drawing->width + SAFETY, // do not overlap + height); + + + + /* copy the bottom of the region */ + gdk_draw_drawable (pixmap, + drawing->drawing_area->style->black_gc, + drawing->pixmap, + 0, y, + 0, y + height, + drawing->width+SAFETY, drawing->height - y + SAFETY); + + + + + if (drawing->pixmap) + gdk_pixmap_unref(drawing->pixmap); + + drawing->pixmap = pixmap; + + drawing->height+=height; + + /* Rectangle to update, from new drawing dimensions */ + //update_rect.x = 0 ; + //update_rect.y = y ; + //update_rect.width = drawing->width; + //update_rect.height = drawing->height - y ; + //gtk_widget_draw( drawing->drawing_area, &update_rect); +} + + +/* Remove a square corresponding to a removed process in the list */ +void drawing_remove_square(Drawing_t *drawing, + guint y, + guint height) +{ + //GdkRectangle update_rect; + + /* Allocate a new pixmap with new height */ + GdkPixmap *pixmap = gdk_pixmap_new( + drawing->drawing_area->window, + drawing->width + SAFETY, + drawing->height - height + SAFETY, + -1); + + /* Copy the high region */ + gdk_draw_drawable (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_drawable (pixmap, + drawing->drawing_area->style->black_gc, + drawing->pixmap, + 0, y + height, + 0, y, + drawing->width, drawing->height - y - height + SAFETY); + + + if (drawing->pixmap) + gdk_pixmap_unref(drawing->pixmap); + + drawing->pixmap = pixmap; + + drawing->height-=height; + + /* Rectangle to update, from new drawing dimensions */ + //update_rect.x = 0 ; + //update_rect.y = y ; + //update_rect.width = drawing->width; + //update_rect.height = drawing->height - y ; + //gtk_widget_draw( drawing->drawing_area, &update_rect); +} + + diff --git a/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Drawing.h b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Drawing.h new file mode 100644 index 00000000..d4b6afd6 --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Drawing.h @@ -0,0 +1,96 @@ +#ifndef _DRAWING_H +#define _DRAWING_H + +#include +#include +#include +#include +#include "CFV.h" +#include "Draw_Item.h" + + +#define SAFETY 50 // safety pixels at right and bottom of pixmap buffer + +/* 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. + */ + +typedef struct _Drawing_t Drawing_t; + +struct _Drawing_t { + GtkWidget *drawing_area; + GdkPixmap *pixmap; + ControlFlowData *control_flow_data; + + PangoLayout *pango_layout; + + gint height, width, depth; + +}; + +Drawing_t *drawing_construct(ControlFlowData *control_flow_data); +void drawing_destroy(Drawing_t *drawing); + +GtkWidget *drawing_get_widget(Drawing_t *drawing); + +//void drawing_Refresh ( Drawing_t *drawing, +// guint x, guint y, +// guint width, guint height); + +void drawing_draw_line( Drawing_t *drawing, + GdkPixmap *pixmap, + guint x1, guint y1, + guint x2, guint y2, + GdkGC *GC); + +//void drawing_copy( Drawing_t *drawing, +// guint xsrc, guint ysrc, +// guint xdest, guint ydest, +// guint width, guint height); + +/* Insert a square corresponding to a new process in the list */ +void drawing_insert_square(Drawing_t *drawing, + guint y, + guint height); + +/* Remove a square corresponding to a removed process in the list */ +void drawing_remove_square(Drawing_t *drawing, + guint y, + guint height); + + +//void drawing_Resize(Drawing_t *drawing, guint h, guint w); + +void convert_pixels_to_time( + gint width, + guint x, + LttTime *window_time_begin, + LttTime *window_time_end, + LttTime *time); + +void convert_time_to_pixels( + LttTime window_time_begin, + LttTime window_time_end, + LttTime time, + gint width, + guint *x); + +#endif // _DRAWING_H diff --git a/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Event_Hooks.c b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Event_Hooks.c new file mode 100644 index 00000000..2905f6bd --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Event_Hooks.c @@ -0,0 +1,1205 @@ +/***************************************************************************** + * Hooks to be called by the main window * + *****************************************************************************/ + + +#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) + +//#define PANGO_ENABLE_BACKEND +#include +#include +#include +#include +#include + +//#include + +#include +#include +#include + +#include +#include +#include +#include + + +#include "Event_Hooks.h" +#include "CFV.h" +#include "Process_List.h" +#include "Drawing.h" +#include "CFV-private.h" + + +#define MAX_PATH_LEN 256 + + +/** + * Event Viewer's constructor hook + * + * This constructor is given as a parameter to the menuitem and toolbar button + * registration. It creates the list. + * @param mw A pointer to the parent window. + * @return The widget created. + */ +GtkWidget * +h_guicontrolflow(MainWindow *mw, LttvTracesetSelector * s, char * key) +{ + g_info("h_guicontrolflow, %p, %p, %s", mw, s, key); + ControlFlowData *control_flow_data = guicontrolflow() ; + + control_flow_data->mw = mw; + TimeWindow *time_window = guicontrolflow_get_time_window(control_flow_data); + time_window->start_time.tv_sec = 0; + time_window->start_time.tv_nsec = 0; + time_window->time_width.tv_sec = 0; + time_window->time_width.tv_nsec = 0; + + LttTime *current_time = guicontrolflow_get_current_time(control_flow_data); + current_time->tv_sec = 0; + current_time->tv_nsec = 0; + + //g_critical("time width1 : %u",time_window->time_width); + + get_time_window(mw, + time_window); + get_current_time(mw, + current_time); + + //g_critical("time width2 : %u",time_window->time_width); + // Unreg done in the GuiControlFlow_Destructor + reg_update_time_window(update_time_window_hook, control_flow_data, + mw); + reg_update_current_time(update_current_time_hook, control_flow_data, + mw); + return guicontrolflow_get_widget(control_flow_data) ; + +} + +int event_selected_hook(void *hook_data, void *call_data) +{ + ControlFlowData *control_flow_data = (ControlFlowData*) hook_data; + guint *event_number = (guint*) call_data; + + g_critical("DEBUG : event selected by main window : %u", *event_number); + +// control_flow_data->currently_Selected_Event = *event_number; +// control_flow_data->Selected_Event = TRUE ; + +// tree_v_set_cursor(control_flow_data); + +} + +/* Hook called before drawing. Gets the initial context at the beginning of the + * drawing interval and copy it to the context in event_request. + */ +int draw_before_hook(void *hook_data, void *call_data) +{ + EventRequest *event_request = (EventRequest*)hook_data; + //EventsContext Events_Context = (EventsContext*)call_data; + + //event_request->Events_Context = Events_Context; + + return 0; +} + +/* + * 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. + * + * 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 draw_event_hook(void *hook_data, void *call_data) +{ + EventRequest *event_request = (EventRequest*)hook_data; + ControlFlowData *control_flow_data = event_request->control_flow_data; + + LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; + + LttvTracefileState *tfs = (LttvTracefileState *)call_data; + + + LttEvent *e; + e = tfc->e; + + if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e)),"schedchange") == 0) + { + g_critical("schedchange!"); + + /* Add process to process list (if not present) and get drawing "y" from + * process position */ + guint pid_out, pid_in; + LttvProcessState *process_out, *process_in; + LttTime birth; + guint y_in = 0, y_out = 0, height = 0, pl_height = 0; + + ProcessList *process_list = + guicontrolflow_get_process_list(event_request->control_flow_data); + + + LttField *f = ltt_event_field(e); + LttField *element; + element = ltt_field_member(f,0); + pid_out = ltt_event_get_long_unsigned(e,element); + element = ltt_field_member(f,1); + pid_in = ltt_event_get_long_unsigned(e,element); + g_critical("out : %u in : %u", pid_out, pid_in); + + + /* Find process pid_out in the list... */ + process_out = lttv_state_find_process(tfs, pid_out); + g_critical("out : %s",g_quark_to_string(process_out->state->s)); + + birth = process_out->creation_time; + gchar *name = strdup(g_quark_to_string(process_out->name)); + HashedProcessData *hashed_process_data_out = NULL; + + if(processlist_get_process_pixels(process_list, + pid_out, + &birth, + &y_out, + &height, + &hashed_process_data_out) == 1) + { + /* Process not present */ + processlist_add(process_list, + pid_out, + &birth, + name, + &pl_height, + &hashed_process_data_out); + processlist_get_process_pixels(process_list, + pid_out, + &birth, + &y_out, + &height, + &hashed_process_data_out); + drawing_insert_square( event_request->control_flow_data->drawing, y_out, height); + } + + g_free(name); + + /* Find process pid_in in the list... */ + process_in = lttv_state_find_process(tfs, pid_in); + g_critical("in : %s",g_quark_to_string(process_in->state->s)); + + birth = process_in->creation_time; + name = strdup(g_quark_to_string(process_in->name)); + HashedProcessData *hashed_process_data_in = NULL; + + if(processlist_get_process_pixels(process_list, + pid_in, + &birth, + &y_in, + &height, + &hashed_process_data_in) == 1) + { + /* Process not present */ + processlist_add(process_list, + pid_in, + &birth, + name, + &pl_height, + &hashed_process_data_in); + processlist_get_process_pixels(process_list, + pid_in, + &birth, + &y_in, + &height, + &hashed_process_data_in); + + drawing_insert_square( event_request->control_flow_data->drawing, y_in, height); + } + g_free(name); + + + /* Find pixels corresponding to time of the event. If the time does + * not fit in the window, show a warning, not supposed to happend. */ + guint x = 0; + guint width = control_flow_data->drawing->drawing_area->allocation.width; + + LttTime time = ltt_event_time(e); + + LttTime window_end = ltt_time_add(control_flow_data->time_window.time_width, + control_flow_data->time_window.start_time); + + + convert_time_to_pixels( + control_flow_data->time_window.start_time, + window_end, + time, + width, + &x); + + assert(x <= width); + + /* draw what represents the event for outgoing process. */ + + DrawContext *draw_context_out = hashed_process_data_out->draw_context; + draw_context_out->current->modify_over->x = x; + draw_context_out->current->modify_over->y = y_out; + draw_context_out->drawable = control_flow_data->drawing->pixmap; + draw_context_out->pango_layout = control_flow_data->drawing->pango_layout; + GtkWidget *widget = control_flow_data->drawing->drawing_area; + //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)]; + draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap); + gdk_gc_copy(draw_context_out->gc, widget->style->black_gc); + //draw_context_out->gc = widget->style->black_gc; + + //draw_arc((void*)&prop_arc, (void*)draw_context_out); + //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap); + + GdkColor colorfg_out = { 0, 0xffff, 0x0000, 0x0000 }; + GdkColor colorbg_out = { 0, 0xffff, 0xffff, 0xffff }; + PropertiesText prop_text_out; + prop_text_out.foreground = &colorfg_out; + prop_text_out.background = &colorbg_out; + prop_text_out.size = 10; + prop_text_out.position = OVER; + + /* Print status of the process : U, WF, WC, E, W, R */ + if(process_out->state->s == LTTV_STATE_UNNAMED) + prop_text_out.text = "U"; + else if(process_out->state->s == LTTV_STATE_WAIT_FORK) + prop_text_out.text = "WF"; + else if(process_out->state->s == LTTV_STATE_WAIT_CPU) + prop_text_out.text = "WC"; + else if(process_out->state->s == LTTV_STATE_EXIT) + prop_text_out.text = "E"; + else if(process_out->state->s == LTTV_STATE_WAIT) + prop_text_out.text = "W"; + else if(process_out->state->s == LTTV_STATE_RUN) + prop_text_out.text = "R"; + else + prop_text_out.text = "U"; + + draw_text((void*)&prop_text_out, (void*)draw_context_out); + gdk_gc_unref(draw_context_out->gc); + + /* Draw the line of the out process */ + if(draw_context_out->previous->middle->x == -1) + { + draw_context_out->previous->middle->x = event_request->x_begin; + g_critical("out middle x_beg : %u",event_request->x_begin); + } + + draw_context_out->current->middle->x = x; + draw_context_out->current->middle->y = y_out + height/2; + draw_context_out->previous->middle->y = y_out + height/2; + draw_context_out->drawable = control_flow_data->drawing->pixmap; + draw_context_out->pango_layout = control_flow_data->drawing->pango_layout; + //draw_context_out->gc = widget->style->black_gc; + draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap); + gdk_gc_copy(draw_context_out->gc, widget->style->black_gc); + + PropertiesLine prop_line_out; + prop_line_out.color = g_new(GdkColor,1); + prop_line_out.line_width = 4; + prop_line_out.style = GDK_LINE_SOLID; + prop_line_out.position = MIDDLE; + + /* color of line : status of the process */ + if(process_out->state->s == LTTV_STATE_UNNAMED) + { + prop_line_out.color->red = 0x0000; + prop_line_out.color->green = 0x0000; + prop_line_out.color->blue = 0x0000; + } + else if(process_out->state->s == LTTV_STATE_WAIT_FORK) + { + prop_line_out.color->red = 0x0fff; + prop_line_out.color->green = 0x0000; + prop_line_out.color->blue = 0x0fff; + } + else if(process_out->state->s == LTTV_STATE_WAIT_CPU) + { + prop_line_out.color->red = 0x0fff; + prop_line_out.color->green = 0x0fff; + prop_line_out.color->blue = 0x0000; + } + else if(process_out->state->s == LTTV_STATE_EXIT) + { + prop_line_out.color->red = 0xffff; + prop_line_out.color->green = 0x0000; + prop_line_out.color->blue = 0xffff; + } + else if(process_out->state->s == LTTV_STATE_WAIT) + { + prop_line_out.color->red = 0xffff; + prop_line_out.color->green = 0x0000; + prop_line_out.color->blue = 0x0000; + } + else if(process_out->state->s == LTTV_STATE_RUN) + { + prop_line_out.color->red = 0x0000; + prop_line_out.color->green = 0xffff; + prop_line_out.color->blue = 0x0000; + } + else + { + prop_line_out.color->red = 0x0000; + prop_line_out.color->green = 0x0000; + prop_line_out.color->blue = 0x0000; + } + + draw_line((void*)&prop_line_out, (void*)draw_context_out); + g_free(prop_line_out.color); + gdk_gc_unref(draw_context_out->gc); + /* Note : finishing line will have to be added when trace read over. */ + + /* Finally, update the drawing context of the pid_in. */ + + DrawContext *draw_context_in = hashed_process_data_in->draw_context; + draw_context_in->current->modify_over->x = x; + draw_context_in->current->modify_over->y = y_in; + draw_context_in->drawable = control_flow_data->drawing->pixmap; + draw_context_in->pango_layout = control_flow_data->drawing->pango_layout; + widget = control_flow_data->drawing->drawing_area; + //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)]; + //draw_context_in->gc = widget->style->black_gc; + draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap); + gdk_gc_copy(draw_context_in->gc, widget->style->black_gc); + + //draw_arc((void*)&prop_arc, (void*)draw_context_in); + //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap); + + GdkColor colorfg_in = { 0, 0x0000, 0xffff, 0x0000 }; + GdkColor colorbg_in = { 0, 0xffff, 0xffff, 0xffff }; + PropertiesText prop_text_in; + prop_text_in.foreground = &colorfg_in; + prop_text_in.background = &colorbg_in; + prop_text_in.size = 10; + prop_text_in.position = OVER; + + /* Print status of the process : U, WF, WC, E, W, R */ + if(process_in->state->s == LTTV_STATE_UNNAMED) + prop_text_in.text = "U"; + else if(process_in->state->s == LTTV_STATE_WAIT_FORK) + prop_text_in.text = "WF"; + else if(process_in->state->s == LTTV_STATE_WAIT_CPU) + prop_text_in.text = "WC"; + else if(process_in->state->s == LTTV_STATE_EXIT) + prop_text_in.text = "E"; + else if(process_in->state->s == LTTV_STATE_WAIT) + prop_text_in.text = "W"; + else if(process_in->state->s == LTTV_STATE_RUN) + prop_text_in.text = "R"; + else + prop_text_in.text = "U"; + + draw_text((void*)&prop_text_in, (void*)draw_context_in); + gdk_gc_unref(draw_context_in->gc); + + /* Draw the line of the in process */ + if(draw_context_in->previous->middle->x == -1) + { + draw_context_in->previous->middle->x = event_request->x_begin; + g_critical("in middle x_beg : %u",event_request->x_begin); + } + + draw_context_in->current->middle->x = x; + draw_context_in->previous->middle->y = y_in + height/2; + draw_context_in->current->middle->y = y_in + height/2; + draw_context_in->drawable = control_flow_data->drawing->pixmap; + draw_context_in->pango_layout = control_flow_data->drawing->pango_layout; + //draw_context_in->gc = widget->style->black_gc; + draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap); + gdk_gc_copy(draw_context_in->gc, widget->style->black_gc); + + PropertiesLine prop_line_in; + prop_line_in.color = g_new(GdkColor,1); + prop_line_in.line_width = 4; + prop_line_in.style = GDK_LINE_SOLID; + prop_line_in.position = MIDDLE; + + /* color of line : status of the process */ + if(process_in->state->s == LTTV_STATE_UNNAMED) + { + prop_line_in.color->red = 0x0000; + prop_line_in.color->green = 0x0000; + prop_line_in.color->blue = 0x0000; + } + else if(process_in->state->s == LTTV_STATE_WAIT_FORK) + { + prop_line_in.color->red = 0x0fff; + prop_line_in.color->green = 0x0000; + prop_line_in.color->blue = 0x0fff; + } + else if(process_in->state->s == LTTV_STATE_WAIT_CPU) + { + prop_line_in.color->red = 0x0fff; + prop_line_in.color->green = 0x0fff; + prop_line_in.color->blue = 0x0000; + } + else if(process_in->state->s == LTTV_STATE_EXIT) + { + prop_line_in.color->red = 0xffff; + prop_line_in.color->green = 0x0000; + prop_line_in.color->blue = 0xffff; + } + else if(process_in->state->s == LTTV_STATE_WAIT) + { + prop_line_in.color->red = 0xffff; + prop_line_in.color->green = 0x0000; + prop_line_in.color->blue = 0x0000; + } + else if(process_in->state->s == LTTV_STATE_RUN) + { + prop_line_in.color->red = 0x0000; + prop_line_in.color->green = 0xffff; + prop_line_in.color->blue = 0x0000; + } + else + { + prop_line_in.color->red = 0x0000; + prop_line_in.color->green = 0x0000; + prop_line_in.color->blue = 0x0000; + } + + draw_line((void*)&prop_line_in, (void*)draw_context_in); + g_free(prop_line_in.color); + gdk_gc_unref(draw_context_in->gc); + } + + return 0; + + /* Temp dump */ +#ifdef DONTSHOW + GString *string = g_string_new("");; + gboolean field_names = TRUE, state = TRUE; + + lttv_event_to_string(e, tfc->tf, string, TRUE, field_names, tfs); + g_string_append_printf(string,"\n"); + + if(state) { + g_string_append_printf(string, " %s", + g_quark_to_string(tfs->process->state->s)); + } + + g_info("%s",string->str); + + g_string_free(string, TRUE); + + /* End of text dump */ +#endif //DONTSHOW + +} + + +int draw_after_hook(void *hook_data, void *call_data) +{ + EventRequest *event_request = (EventRequest*)hook_data; + ControlFlowData *control_flow_data = event_request->control_flow_data; + + LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; + + LttvTracefileState *tfs = (LttvTracefileState *)call_data; + + + LttEvent *e; + e = tfc->e; + + if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e)),"schedchange") == 0) + { + g_critical("schedchange!"); + + /* Add process to process list (if not present) and get drawing "y" from + * process position */ + guint pid_out, pid_in; + LttvProcessState *process_out, *process_in; + LttTime birth; + guint y_in = 0, y_out = 0, height = 0, pl_height = 0; + + ProcessList *process_list = + guicontrolflow_get_process_list(event_request->control_flow_data); + + + LttField *f = ltt_event_field(e); + LttField *element; + element = ltt_field_member(f,0); + pid_out = ltt_event_get_long_unsigned(e,element); + element = ltt_field_member(f,1); + pid_in = ltt_event_get_long_unsigned(e,element); + g_critical("out : %u in : %u", pid_out, pid_in); + + + /* Find process pid_out in the list... */ + process_out = lttv_state_find_process(tfs, pid_out); + g_critical("out : %s",g_quark_to_string(process_out->state->s)); + + birth = process_out->creation_time; + gchar *name = strdup(g_quark_to_string(process_out->name)); + HashedProcessData *hashed_process_data_out = NULL; + + if(processlist_get_process_pixels(process_list, + pid_out, + &birth, + &y_out, + &height, + &hashed_process_data_out) == 1) + { + /* Process not present */ + processlist_add(process_list, + pid_out, + &birth, + name, + &pl_height, + &hashed_process_data_out); + processlist_get_process_pixels(process_list, + pid_out, + &birth, + &y_out, + &height, + &hashed_process_data_out); + drawing_insert_square( event_request->control_flow_data->drawing, y_out, height); + } + + g_free(name); + + /* Find process pid_in in the list... */ + process_in = lttv_state_find_process(tfs, pid_in); + g_critical("in : %s",g_quark_to_string(process_in->state->s)); + + birth = process_in->creation_time; + name = strdup(g_quark_to_string(process_in->name)); + HashedProcessData *hashed_process_data_in = NULL; + + if(processlist_get_process_pixels(process_list, + pid_in, + &birth, + &y_in, + &height, + &hashed_process_data_in) == 1) + { + /* Process not present */ + processlist_add(process_list, + pid_in, + &birth, + name, + &pl_height, + &hashed_process_data_in); + processlist_get_process_pixels(process_list, + pid_in, + &birth, + &y_in, + &height, + &hashed_process_data_in); + + drawing_insert_square( event_request->control_flow_data->drawing, y_in, height); + } + g_free(name); + + + /* Find pixels corresponding to time of the event. If the time does + * not fit in the window, show a warning, not supposed to happend. */ + //guint x = 0; + //guint width = control_flow_data->drawing->drawing_area->allocation.width; + + //LttTime time = ltt_event_time(e); + + //LttTime window_end = ltt_time_add(control_flow_data->time_window.time_width, + // control_flow_data->time_window.start_time); + + + //convert_time_to_pixels( + // control_flow_data->time_window.start_time, + // window_end, + // time, + // width, + // &x); + + //assert(x <= width); + + /* draw what represents the event for outgoing process. */ + + DrawContext *draw_context_out = hashed_process_data_out->draw_context; + //draw_context_out->current->modify_over->x = x; + draw_context_out->current->modify_over->y = y_out; + draw_context_out->drawable = control_flow_data->drawing->pixmap; + draw_context_out->pango_layout = control_flow_data->drawing->pango_layout; + GtkWidget *widget = control_flow_data->drawing->drawing_area; + //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)]; + draw_context_out->gc = widget->style->black_gc; + + //draw_arc((void*)&prop_arc, (void*)draw_context_out); + //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap); + + GdkColor colorfg_out = { 0, 0xffff, 0x0000, 0x0000 }; + GdkColor colorbg_out = { 0, 0xffff, 0xffff, 0xffff }; + PropertiesText prop_text_out; + prop_text_out.foreground = &colorfg_out; + prop_text_out.background = &colorbg_out; + prop_text_out.size = 10; + prop_text_out.position = OVER; + + /* Print status of the process : U, WF, WC, E, W, R */ + if(process_out->state->s == LTTV_STATE_UNNAMED) + prop_text_out.text = "U"; + else if(process_out->state->s == LTTV_STATE_WAIT_FORK) + prop_text_out.text = "WF"; + else if(process_out->state->s == LTTV_STATE_WAIT_CPU) + prop_text_out.text = "WC"; + else if(process_out->state->s == LTTV_STATE_EXIT) + prop_text_out.text = "E"; + else if(process_out->state->s == LTTV_STATE_WAIT) + prop_text_out.text = "W"; + else if(process_out->state->s == LTTV_STATE_RUN) + prop_text_out.text = "R"; + else + prop_text_out.text = "U"; + + draw_text((void*)&prop_text_out, (void*)draw_context_out); + + draw_context_out->current->middle->y = y_out+height/2; + draw_context_out->current->status = process_out->state->s; + + /* for pid_out : remove previous, Prev = current, new current (default) */ + g_free(draw_context_out->previous->modify_under); + g_free(draw_context_out->previous->modify_middle); + g_free(draw_context_out->previous->modify_over); + g_free(draw_context_out->previous->under); + g_free(draw_context_out->previous->middle); + g_free(draw_context_out->previous->over); + g_free(draw_context_out->previous); + + draw_context_out->previous = draw_context_out->current; + + draw_context_out->current = g_new(DrawInfo,1); + draw_context_out->current->over = g_new(ItemInfo,1); + draw_context_out->current->over->x = -1; + draw_context_out->current->over->y = -1; + draw_context_out->current->middle = g_new(ItemInfo,1); + draw_context_out->current->middle->x = -1; + draw_context_out->current->middle->y = -1; + draw_context_out->current->under = g_new(ItemInfo,1); + draw_context_out->current->under->x = -1; + draw_context_out->current->under->y = -1; + draw_context_out->current->modify_over = g_new(ItemInfo,1); + draw_context_out->current->modify_over->x = -1; + draw_context_out->current->modify_over->y = -1; + draw_context_out->current->modify_middle = g_new(ItemInfo,1); + draw_context_out->current->modify_middle->x = -1; + draw_context_out->current->modify_middle->y = -1; + draw_context_out->current->modify_under = g_new(ItemInfo,1); + draw_context_out->current->modify_under->x = -1; + draw_context_out->current->modify_under->y = -1; + draw_context_out->current->status = LTTV_STATE_UNNAMED; + + /* Finally, update the drawing context of the pid_in. */ + + DrawContext *draw_context_in = hashed_process_data_in->draw_context; + //draw_context_in->current->modify_over->x = x; + draw_context_in->current->modify_over->y = y_in; + draw_context_in->drawable = control_flow_data->drawing->pixmap; + draw_context_in->pango_layout = control_flow_data->drawing->pango_layout; + widget = control_flow_data->drawing->drawing_area; + //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)]; + draw_context_in->gc = widget->style->black_gc; + + //draw_arc((void*)&prop_arc, (void*)draw_context_in); + //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap); + + GdkColor colorfg_in = { 0, 0x0000, 0xffff, 0x0000 }; + GdkColor colorbg_in = { 0, 0xffff, 0xffff, 0xffff }; + PropertiesText prop_text_in; + prop_text_in.foreground = &colorfg_in; + prop_text_in.background = &colorbg_in; + prop_text_in.size = 10; + prop_text_in.position = OVER; + + /* Print status of the process : U, WF, WC, E, W, R */ + if(process_in->state->s == LTTV_STATE_UNNAMED) + prop_text_in.text = "U"; + else if(process_in->state->s == LTTV_STATE_WAIT_FORK) + prop_text_in.text = "WF"; + else if(process_in->state->s == LTTV_STATE_WAIT_CPU) + prop_text_in.text = "WC"; + else if(process_in->state->s == LTTV_STATE_EXIT) + prop_text_in.text = "E"; + else if(process_in->state->s == LTTV_STATE_WAIT) + prop_text_in.text = "W"; + else if(process_in->state->s == LTTV_STATE_RUN) + prop_text_in.text = "R"; + else + prop_text_in.text = "U"; + + draw_text((void*)&prop_text_in, (void*)draw_context_in); + + draw_context_in->current->middle->y = y_in+height/2; + draw_context_in->current->status = process_in->state->s; + + /* for pid_in : remove previous, Prev = current, new current (default) */ + g_free(draw_context_in->previous->modify_under); + g_free(draw_context_in->previous->modify_middle); + g_free(draw_context_in->previous->modify_over); + g_free(draw_context_in->previous->under); + g_free(draw_context_in->previous->middle); + g_free(draw_context_in->previous->over); + g_free(draw_context_in->previous); + + draw_context_in->previous = draw_context_in->current; + + draw_context_in->current = g_new(DrawInfo,1); + draw_context_in->current->over = g_new(ItemInfo,1); + draw_context_in->current->over->x = -1; + draw_context_in->current->over->y = -1; + draw_context_in->current->middle = g_new(ItemInfo,1); + draw_context_in->current->middle->x = -1; + draw_context_in->current->middle->y = -1; + draw_context_in->current->under = g_new(ItemInfo,1); + draw_context_in->current->under->x = -1; + draw_context_in->current->under->y = -1; + draw_context_in->current->modify_over = g_new(ItemInfo,1); + draw_context_in->current->modify_over->x = -1; + draw_context_in->current->modify_over->y = -1; + draw_context_in->current->modify_middle = g_new(ItemInfo,1); + draw_context_in->current->modify_middle->x = -1; + draw_context_in->current->modify_middle->y = -1; + draw_context_in->current->modify_under = g_new(ItemInfo,1); + draw_context_in->current->modify_under->x = -1; + draw_context_in->current->modify_under->y = -1; + draw_context_in->current->status = LTTV_STATE_UNNAMED; + + } + + return 0; +} + + + + +gint update_time_window_hook(void *hook_data, void *call_data) +{ + ControlFlowData *control_flow_data = (ControlFlowData*) hook_data; + TimeWindow *old_time_window = + guicontrolflow_get_time_window(control_flow_data); + TimeWindow *new_time_window = ((TimeWindow*)call_data); + + /* 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 : %u, %u to %u, %u", + old_time_window->start_time.tv_sec, + old_time_window->start_time.tv_nsec, + old_time_window->time_width.tv_sec, + old_time_window->time_width.tv_nsec); + + g_info("New time window HOOK : %u, %u to %u, %u", + new_time_window->start_time.tv_sec, + new_time_window->start_time.tv_nsec, + new_time_window->time_width.tv_sec, + new_time_window->time_width.tv_nsec); + + if( new_time_window->time_width.tv_sec == old_time_window->time_width.tv_sec + && new_time_window->time_width.tv_nsec == old_time_window->time_width.tv_nsec) + { + /* Same scale (scrolling) */ + g_info("scrolling"); + LttTime *ns = &new_time_window->start_time; + LttTime *os = &old_time_window->start_time; + LttTime old_end = ltt_time_add(old_time_window->start_time, + old_time_window->time_width); + LttTime new_end = ltt_time_add(new_time_window->start_time, + new_time_window->time_width); + //if(nsdrawing->drawing_area->allocation.width; + convert_time_to_pixels( + *os, + old_end, + *ns, + width, + &x); + + /* Copy old data to new location */ + gdk_draw_drawable (control_flow_data->drawing->pixmap, + control_flow_data->drawing->drawing_area->style->white_gc, + control_flow_data->drawing->pixmap, + x, 0, + 0, 0, + -1, -1); + + convert_time_to_pixels( + *ns, + new_end, + old_end, + width, + &x); + + *old_time_window = *new_time_window; + /* Clear the data request background, but not SAFETY */ + gdk_draw_rectangle (control_flow_data->drawing->pixmap, + control_flow_data->drawing->drawing_area->style->white_gc, + TRUE, + x+SAFETY, 0, + control_flow_data->drawing->width - x, // do not overlap + control_flow_data->drawing->height+SAFETY); + /* Get new data for the rest. */ + drawing_data_request(control_flow_data->drawing, + &control_flow_data->drawing->pixmap, + x, 0, + control_flow_data->drawing->width - x, + control_flow_data->drawing->height); + + drawing_refresh(control_flow_data->drawing, + 0, 0, + control_flow_data->drawing->width, + control_flow_data->drawing->height); + + + } else { + //if(nsdrawing->drawing_area->allocation.width; + convert_time_to_pixels( + *ns, + new_end, + *os, + width, + &x); + + /* Copy old data to new location */ + gdk_draw_drawable (control_flow_data->drawing->pixmap, + control_flow_data->drawing->drawing_area->style->white_gc, + control_flow_data->drawing->pixmap, + 0, 0, + x, 0, + -1, -1); + + *old_time_window = *new_time_window; + + /* Clean the data request background */ + gdk_draw_rectangle (control_flow_data->drawing->pixmap, + control_flow_data->drawing->drawing_area->style->white_gc, + TRUE, + 0, 0, + x, // do not overlap + control_flow_data->drawing->height+SAFETY); + /* Get new data for the rest. */ + drawing_data_request(control_flow_data->drawing, + &control_flow_data->drawing->pixmap, + 0, 0, + x, + control_flow_data->drawing->height); + + drawing_refresh(control_flow_data->drawing, + 0, 0, + control_flow_data->drawing->width, + control_flow_data->drawing->height); + + } else { + g_info("scrolling far"); + /* Cannot reuse any part of the screen : far jump */ + *old_time_window = *new_time_window; + + + gdk_draw_rectangle (control_flow_data->drawing->pixmap, + control_flow_data->drawing->drawing_area->style->white_gc, + TRUE, + 0, 0, + control_flow_data->drawing->width+SAFETY, // do not overlap + control_flow_data->drawing->height+SAFETY); + + drawing_data_request(control_flow_data->drawing, + &control_flow_data->drawing->pixmap, + 0, 0, + control_flow_data->drawing->width, + control_flow_data->drawing->height); + + drawing_refresh(control_flow_data->drawing, + 0, 0, + control_flow_data->drawing->width, + control_flow_data->drawing->height); + } + } + } else { + /* Different scale (zoom) */ + g_info("zoom"); + + *old_time_window = *new_time_window; + + gdk_draw_rectangle (control_flow_data->drawing->pixmap, + control_flow_data->drawing->drawing_area->style->white_gc, + TRUE, + 0, 0, + control_flow_data->drawing->width+SAFETY, // do not overlap + control_flow_data->drawing->height+SAFETY); + + + drawing_data_request(control_flow_data->drawing, + &control_flow_data->drawing->pixmap, + 0, 0, + control_flow_data->drawing->width, + control_flow_data->drawing->height); + + drawing_refresh(control_flow_data->drawing, + 0, 0, + control_flow_data->drawing->width, + control_flow_data->drawing->height); + } + + return 0; +} + +gint update_current_time_hook(void *hook_data, void *call_data) +{ + ControlFlowData *control_flow_data = (ControlFlowData*)hook_data; + + LttTime* current_time = + guicontrolflow_get_current_time(control_flow_data); + *current_time = *((LttTime*)call_data); + + TimeWindow time_window; + + LttTime time_begin = control_flow_data->time_window.start_time; + LttTime width = control_flow_data->time_window.time_width; + LttTime half_width = ltt_time_div(width,2.0); + LttTime time_end = ltt_time_add(time_begin, width); + + LttvTracesetContext * tsc = + get_traceset_context(control_flow_data->mw); + + LttTime trace_start = tsc->Time_Span->startTime; + LttTime trace_end = tsc->Time_Span->endTime; + + g_info("New current time HOOK : %u, %u", 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) == -1) + { + if(ltt_time_compare(*current_time, + ltt_time_add(trace_start,half_width)) == -1) + time_begin = trace_start; + else + time_begin = ltt_time_sub(*current_time,half_width); + + time_window.start_time = time_begin; + time_window.time_width = width; + + set_time_window(control_flow_data->mw, &time_window); + } + else if(ltt_time_compare(*current_time, time_end) == 1) + { + if(ltt_time_compare(*current_time, ltt_time_sub(trace_end, half_width)) == 1) + time_begin = ltt_time_sub(trace_end,width); + else + time_begin = ltt_time_sub(*current_time,half_width); + + time_window.start_time = time_begin; + time_window.time_width = width; + + set_time_window(control_flow_data->mw, &time_window); + + } + gtk_widget_queue_draw(control_flow_data->drawing->drawing_area); + + return 0; +} + +typedef struct _ClosureData { + EventRequest *event_request; + LttvTraceState *ts; +} ClosureData; + + +void draw_closure(gpointer key, gpointer value, gpointer user_data) +{ + ProcessInfo *process_info = (ProcessInfo*)key; + HashedProcessData *hashed_process_data = (HashedProcessData*)value; + ClosureData *closure_data = (ClosureData*)user_data; + + ControlFlowData *control_flow_data = + closure_data->event_request->control_flow_data; + + GtkWidget *widget = control_flow_data->drawing->drawing_area; + + /* Get y position of process */ + gint y=0, height=0; + + processlist_get_pixels_from_data( control_flow_data->process_list, + process_info, + hashed_process_data, + &y, + &height); + /* Get last state of process */ + LttvTraceContext *tc = + (LttvTraceContext *)closure_data->ts; + + LttvTraceState *ts = closure_data->ts; + LttvProcessState *process; + + process = lttv_state_find_process((LttvTracefileState*)ts, process_info->pid); + + /* Draw the closing line */ + DrawContext *draw_context = hashed_process_data->draw_context; + if(draw_context->previous->middle->x == -1) + { + draw_context->previous->middle->x = closure_data->event_request->x_begin; + g_critical("out middle x_beg : %u",closure_data->event_request->x_begin); + } + + draw_context->current->middle->x = closure_data->event_request->x_end; + draw_context->current->middle->y = y + height/2; + draw_context->previous->middle->y = y + height/2; + draw_context->drawable = control_flow_data->drawing->pixmap; + draw_context->pango_layout = control_flow_data->drawing->pango_layout; + //draw_context->gc = widget->style->black_gc; + draw_context->gc = gdk_gc_new(control_flow_data->drawing->pixmap); + gdk_gc_copy(draw_context->gc, widget->style->black_gc); + + PropertiesLine prop_line; + prop_line.color = g_new(GdkColor,1); + prop_line.line_width = 6; + prop_line.style = GDK_LINE_SOLID; + prop_line.position = MIDDLE; + + /* color of line : status of the process */ + if(process->state->s == LTTV_STATE_UNNAMED) + { + prop_line.color->red = 0x0000; + prop_line.color->green = 0x0000; + prop_line.color->blue = 0x0000; + } + else if(process->state->s == LTTV_STATE_WAIT_FORK) + { + prop_line.color->red = 0x0fff; + prop_line.color->green = 0x0000; + prop_line.color->blue = 0x0fff; + } + else if(process->state->s == LTTV_STATE_WAIT_CPU) + { + prop_line.color->red = 0x0fff; + prop_line.color->green = 0x0fff; + prop_line.color->blue = 0x0000; + } + else if(process->state->s == LTTV_STATE_EXIT) + { + prop_line.color->red = 0xffff; + prop_line.color->green = 0x0000; + prop_line.color->blue = 0xffff; + } + else if(process->state->s == LTTV_STATE_WAIT) + { + prop_line.color->red = 0xffff; + prop_line.color->green = 0x0000; + prop_line.color->blue = 0x0000; + } + else if(process->state->s == LTTV_STATE_RUN) + { + prop_line.color->red = 0x0000; + prop_line.color->green = 0xffff; + prop_line.color->blue = 0x0000; + } + else + { + prop_line.color->red = 0x0000; + prop_line.color->green = 0x0000; + prop_line.color->blue = 0x0000; + } + + draw_line((void*)&prop_line, (void*)draw_context); + g_free(prop_line.color); + gdk_gc_unref(draw_context->gc); + + /* Reset draw_context of the process for next request */ + + hashed_process_data->draw_context->drawable = NULL; + hashed_process_data->draw_context->gc = NULL; + hashed_process_data->draw_context->pango_layout = NULL; + hashed_process_data->draw_context->current->over->x = -1; + hashed_process_data->draw_context->current->over->y = -1; + hashed_process_data->draw_context->current->middle->x = -1; + hashed_process_data->draw_context->current->middle->y = -1; + hashed_process_data->draw_context->current->under->x = -1; + hashed_process_data->draw_context->current->under->y = -1; + hashed_process_data->draw_context->current->modify_over->x = -1; + hashed_process_data->draw_context->current->modify_over->y = -1; + hashed_process_data->draw_context->current->modify_middle->x = -1; + hashed_process_data->draw_context->current->modify_middle->y = -1; + hashed_process_data->draw_context->current->modify_under->x = -1; + hashed_process_data->draw_context->current->modify_under->y = -1; + hashed_process_data->draw_context->current->status = LTTV_STATE_UNNAMED; + hashed_process_data->draw_context->previous->over->x = -1; + hashed_process_data->draw_context->previous->over->y = -1; + hashed_process_data->draw_context->previous->middle->x = -1; + hashed_process_data->draw_context->previous->middle->y = -1; + hashed_process_data->draw_context->previous->under->x = -1; + hashed_process_data->draw_context->previous->under->y = -1; + hashed_process_data->draw_context->previous->modify_over->x = -1; + hashed_process_data->draw_context->previous->modify_over->y = -1; + hashed_process_data->draw_context->previous->modify_middle->x = -1; + hashed_process_data->draw_context->previous->modify_middle->y = -1; + hashed_process_data->draw_context->previous->modify_under->x = -1; + hashed_process_data->draw_context->previous->modify_under->y = -1; + hashed_process_data->draw_context->previous->status = LTTV_STATE_UNNAMED; + + +} + +/* + * for each process + * draw closing line + * new default prev and current + */ +int after_data_request(void *hook_data, void *call_data) +{ + EventRequest *event_request = (EventRequest*)hook_data; + ControlFlowData *control_flow_data = event_request->control_flow_data; + + ProcessList *process_list = + guicontrolflow_get_process_list(event_request->control_flow_data); + + ClosureData closure_data; + closure_data.event_request = (EventRequest*)hook_data; + closure_data.ts = (LttvTraceState*)call_data; + + g_hash_table_foreach(process_list->process_hash, draw_closure, + (void*)&closure_data); + +} + diff --git a/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Event_Hooks.h b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Event_Hooks.h new file mode 100644 index 00000000..66170d3c --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Event_Hooks.h @@ -0,0 +1,84 @@ +/* Event_hooks.c 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 +#include +#include +#include "Process_List.h" +#include "Drawing.h" +#include "CFV.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(ProcessList *process_list, Drawing_t *drawing); + +GtkWidget *h_guicontrolflow(MainWindow *mw, LttvTracesetSelector * s, char * key); + +int event_selected_hook(void *hook_data, void *call_data); + +/* Hook called before drawing. Gets the initial context at the beginning of the + * drawing interval and copy it to the context in event_request. + */ +int draw_before_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. + * + * 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 draw_event_hook(void *hook_data, void *call_data); + +int draw_after_hook(void *hook_data, void *call_data); + +void draw_closure(gpointer key, gpointer value, gpointer user_data); + +int after_data_request(void *hook_data, void *call_data); + + +gint update_time_window_hook(void *hook_data, void *call_data); +gint update_current_time_hook(void *hook_data, void *call_data); + + + + +#endif // _EVENT_HOOKS_H diff --git a/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Makefile.am b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Makefile.am new file mode 100644 index 00000000..a8e1f7b7 --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Makefile.am @@ -0,0 +1,20 @@ +# +# Makefile for LTT New generation user interface : plugins. +# +# Created by Mathieu Desnoyers on September 27, 2003 +# + +AM_CFLAGS = $(GLIB_CFLAGS) +AM_CFLAGS += $(GTK_CFLAGS) +LIBS += $(GLIB_LIBS) +LIBS += $(GTK_LIBS) -L${top_srcdir}/lttv/modules/gui/API -lmainWinApi + +libdir = ${lttvplugindir} + +lib_LTLIBRARIES = libguiControlFlow.la +libguiControlFlow_la_LDFLAGS = -module +libguiControlFlow_la_SOURCES = module.c Event_Hooks.c CFV.c Process_List.c\ + Drawing.c Draw_Item.c + +noinst_HEADERS = Event_Hooks.h CFV.h Process_List.h\ + Drawing.h Draw_Item.h diff --git a/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Process_List.c b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Process_List.c new file mode 100644 index 00000000..c695fb15 --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Process_List.c @@ -0,0 +1,510 @@ + +#include +#include +#include "Process_List.h" +#include "Draw_Item.h" + +/***************************************************************************** + * Methods to synchronize process list * + *****************************************************************************/ + +/* Enumeration of the columns */ +enum +{ + PROCESS_COLUMN, + PID_COLUMN, + BIRTH_S_COLUMN, + BIRTH_NS_COLUMN, + N_COLUMNS +}; + + +gint process_sort_func ( GtkTreeModel *model, + GtkTreeIter *it_a, + GtkTreeIter *it_b, + gpointer user_data) +{ + GValue a, b; + + memset(&a, 0, sizeof(GValue)); + memset(&b, 0, sizeof(GValue)); + + /* Order by PID */ + gtk_tree_model_get_value( model, + it_a, + PID_COLUMN, + &a); + + gtk_tree_model_get_value( model, + it_b, + PID_COLUMN, + &b); + + if(G_VALUE_TYPE(&a) == G_TYPE_UINT + && G_VALUE_TYPE(&b) == G_TYPE_UINT ) + { + if(g_value_get_uint(&a) > g_value_get_uint(&b)) + { + g_value_unset(&a); + g_value_unset(&b); + return 1; + } + if(g_value_get_uint(&a) < g_value_get_uint(&b)) + { + g_value_unset(&a); + g_value_unset(&b); + return 0; + } + } + + g_value_unset(&a); + g_value_unset(&b); + + + /* Order by birth second */ + gtk_tree_model_get_value( model, + it_a, + BIRTH_S_COLUMN, + &a); + + gtk_tree_model_get_value( model, + it_b, + BIRTH_S_COLUMN, + &b); + + + if(G_VALUE_TYPE(&a) == G_TYPE_ULONG + && G_VALUE_TYPE(&b) == G_TYPE_ULONG ) + { + if(g_value_get_ulong(&a) > g_value_get_ulong(&b)) + { + g_value_unset(&a); + g_value_unset(&b); + return 1; + } + if(g_value_get_ulong(&a) < g_value_get_ulong(&b)) + { + g_value_unset(&a); + g_value_unset(&b); + return 0; + } + + } + + g_value_unset(&a); + g_value_unset(&b); + + /* Order by birth nanosecond */ + gtk_tree_model_get_value( model, + it_a, + BIRTH_NS_COLUMN, + &a); + + gtk_tree_model_get_value( model, + it_b, + BIRTH_NS_COLUMN, + &b); + + + if(G_VALUE_TYPE(&a) == G_TYPE_ULONG + && G_VALUE_TYPE(&b) == G_TYPE_ULONG ) + { + if(g_value_get_ulong(&a) > g_value_get_ulong(&b)) + { + g_value_unset(&a); + g_value_unset(&b); + return 1; + } + // Final condition + //if(g_value_get_ulong(&a) < g_value_get_ulong(&b)) + //{ + // g_value_unset(&a); + // g_value_unset(&b); + // return 0; + //} + + } + + g_value_unset(&a); + g_value_unset(&b); + + return 0; + +} + +guint hash_fct(gconstpointer key) +{ + return ((ProcessInfo*)key)->pid; +} + +gboolean equ_fct(gconstpointer a, gconstpointer b) +{ + if(((ProcessInfo*)a)->pid != ((ProcessInfo*)b)->pid) + return 0; +// g_critical("compare %u and %u",((ProcessInfo*)a)->pid,((ProcessInfo*)b)->pid); + if(((ProcessInfo*)a)->birth.tv_sec != ((ProcessInfo*)b)->birth.tv_sec) + return 0; +// g_critical("compare %u and %u",((ProcessInfo*)a)->birth.tv_sec,((ProcessInfo*)b)->birth.tv_sec); + + if(((ProcessInfo*)a)->birth.tv_nsec != ((ProcessInfo*)b)->birth.tv_nsec) + return 0; +// g_critical("compare %u and %u",((ProcessInfo*)a)->birth.tv_nsec,((ProcessInfo*)b)->birth.tv_nsec); + + return 1; +} + +void destroy_hash_key(gpointer key); + +void destroy_hash_data(gpointer data); + + + + +ProcessList *processlist_construct(void) +{ + GtkTreeViewColumn *column; + GtkCellRenderer *renderer; + + ProcessList* process_list = g_new(ProcessList,1); + + process_list->number_of_process = 0; + + /* Create the Process list */ + process_list->list_store = gtk_list_store_new ( N_COLUMNS, + G_TYPE_STRING, + G_TYPE_UINT, + G_TYPE_ULONG, + G_TYPE_ULONG); + + + process_list->process_list_widget = + gtk_tree_view_new_with_model + (GTK_TREE_MODEL (process_list->list_store)); + + g_object_unref (G_OBJECT (process_list->list_store)); + + gtk_tree_sortable_set_sort_func( + GTK_TREE_SORTABLE(process_list->list_store), + PID_COLUMN, + process_sort_func, + NULL, + NULL); + + gtk_tree_sortable_set_sort_column_id( + GTK_TREE_SORTABLE(process_list->list_store), + PID_COLUMN, + GTK_SORT_ASCENDING); + + process_list->process_hash = g_hash_table_new_full( + hash_fct, equ_fct, + destroy_hash_key, destroy_hash_data + ); + + + gtk_tree_view_set_headers_visible( + GTK_TREE_VIEW(process_list->process_list_widget), FALSE); + + /* Create a column, associating the "text" attribute of the + * cell_renderer to the first column of the model */ + /* Columns alignment : 0.0 : Left 0.5 : Center 1.0 : Right */ + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ( "Process", + renderer, + "text", + PROCESS_COLUMN, + NULL); + gtk_tree_view_column_set_alignment (column, 0.0); + gtk_tree_view_column_set_fixed_width (column, 45); + gtk_tree_view_append_column ( + GTK_TREE_VIEW (process_list->process_list_widget), column); + + column = gtk_tree_view_column_new_with_attributes ( "PID", + renderer, + "text", + PID_COLUMN, + NULL); + gtk_tree_view_append_column ( + GTK_TREE_VIEW (process_list->process_list_widget), column); + + + column = gtk_tree_view_column_new_with_attributes ( "Birth sec", + renderer, + "text", + BIRTH_S_COLUMN, + NULL); + gtk_tree_view_append_column ( + GTK_TREE_VIEW (process_list->process_list_widget), column); + + //gtk_tree_view_column_set_visible(column, 0); + // + column = gtk_tree_view_column_new_with_attributes ( "Birth nsec", + renderer, + "text", + BIRTH_NS_COLUMN, + NULL); + gtk_tree_view_append_column ( + GTK_TREE_VIEW (process_list->process_list_widget), column); + + //gtk_tree_view_column_set_visible(column, 0); + + g_object_set_data_full( + G_OBJECT(process_list->process_list_widget), + "process_list_Data", + process_list, + (GDestroyNotify)processlist_destroy); + + return process_list; +} +void processlist_destroy(ProcessList *process_list) +{ + g_hash_table_destroy(process_list->process_hash); + process_list->process_hash = NULL; + + g_free(process_list); +} + +GtkWidget *processlist_get_widget(ProcessList *process_list) +{ + return process_list->process_list_widget; +} + + + +gint get_cell_height(GtkTreeView *tree_view) +{ + gint height; + GtkTreeViewColumn *Column = gtk_tree_view_get_column(tree_view, 0); + //GList *Render_List = gtk_tree_view_column_get_cell_renderers(Column); + //GtkCellRenderer *Renderer = g_list_first(Render_List)->data; + + //g_list_free(Render_List); + gtk_tree_view_column_cell_get_size(Column, NULL, NULL, NULL, NULL, &height); + //g_critical("cell 0 height : %u",height); + + return height; +} + +void destroy_hash_key(gpointer key) +{ + g_free(key); +} + +void destroy_hash_data(gpointer data) +{ + g_free(data); +} + +int processlist_add( ProcessList *process_list, + guint pid, + LttTime *birth, + gchar *name, + guint *height, + HashedProcessData **pm_hashed_process_data) +{ + GtkTreeIter iter ; + ProcessInfo *Process_Info = g_new(ProcessInfo, 1); + HashedProcessData *hashed_process_data = g_new(HashedProcessData, 1); + *pm_hashed_process_data = hashed_process_data; + + Process_Info->pid = pid; + Process_Info->birth = *birth; + + hashed_process_data->draw_context = g_new(DrawContext, 1); + hashed_process_data->draw_context->drawable = NULL; + hashed_process_data->draw_context->gc = NULL; + hashed_process_data->draw_context->pango_layout = NULL; + hashed_process_data->draw_context->current = g_new(DrawInfo,1); + hashed_process_data->draw_context->current->over = g_new(ItemInfo,1); + hashed_process_data->draw_context->current->over->x = -1; + hashed_process_data->draw_context->current->over->y = -1; + hashed_process_data->draw_context->current->middle = g_new(ItemInfo,1); + hashed_process_data->draw_context->current->middle->x = -1; + hashed_process_data->draw_context->current->middle->y = -1; + hashed_process_data->draw_context->current->under = g_new(ItemInfo,1); + hashed_process_data->draw_context->current->under->x = -1; + hashed_process_data->draw_context->current->under->y = -1; + hashed_process_data->draw_context->current->modify_over = g_new(ItemInfo,1); + hashed_process_data->draw_context->current->modify_over->x = -1; + hashed_process_data->draw_context->current->modify_over->y = -1; + hashed_process_data->draw_context->current->modify_middle = g_new(ItemInfo,1); + hashed_process_data->draw_context->current->modify_middle->x = -1; + hashed_process_data->draw_context->current->modify_middle->y = -1; + hashed_process_data->draw_context->current->modify_under = g_new(ItemInfo,1); + hashed_process_data->draw_context->current->modify_under->x = -1; + hashed_process_data->draw_context->current->modify_under->y = -1; + hashed_process_data->draw_context->current->status = LTTV_STATE_UNNAMED; + hashed_process_data->draw_context->previous = g_new(DrawInfo,1); + hashed_process_data->draw_context->previous->over = g_new(ItemInfo,1); + hashed_process_data->draw_context->previous->over->x = -1; + hashed_process_data->draw_context->previous->over->y = -1; + hashed_process_data->draw_context->previous->middle = g_new(ItemInfo,1); + hashed_process_data->draw_context->previous->middle->x = -1; + hashed_process_data->draw_context->previous->middle->y = -1; + hashed_process_data->draw_context->previous->under = g_new(ItemInfo,1); + hashed_process_data->draw_context->previous->under->x = -1; + hashed_process_data->draw_context->previous->under->y = -1; + hashed_process_data->draw_context->previous->modify_over = g_new(ItemInfo,1); + hashed_process_data->draw_context->previous->modify_over->x = -1; + hashed_process_data->draw_context->previous->modify_over->y = -1; + hashed_process_data->draw_context->previous->modify_middle = g_new(ItemInfo,1); + hashed_process_data->draw_context->previous->modify_middle->x = -1; + hashed_process_data->draw_context->previous->modify_middle->y = -1; + hashed_process_data->draw_context->previous->modify_under = g_new(ItemInfo,1); + hashed_process_data->draw_context->previous->modify_under->x = -1; + hashed_process_data->draw_context->previous->modify_under->y = -1; + hashed_process_data->draw_context->previous->status = LTTV_STATE_UNNAMED; + + /* Add a new row to the model */ + gtk_list_store_append ( process_list->list_store, &iter); + //g_critical ( "iter before : %s", gtk_tree_path_to_string ( + // gtk_tree_model_get_path ( + // GTK_TREE_MODEL(process_list->list_store), + // &iter))); + gtk_list_store_set ( process_list->list_store, &iter, + PROCESS_COLUMN, name, + PID_COLUMN, pid, + BIRTH_S_COLUMN, birth->tv_sec, + BIRTH_NS_COLUMN, birth->tv_nsec, + -1); + hashed_process_data->row_ref = gtk_tree_row_reference_new ( + GTK_TREE_MODEL(process_list->list_store), + gtk_tree_model_get_path( + GTK_TREE_MODEL(process_list->list_store), + &iter)); + g_hash_table_insert( process_list->process_hash, + (gpointer)Process_Info, + (gpointer)hashed_process_data); + + //g_critical ( "iter after : %s", gtk_tree_path_to_string ( + // gtk_tree_model_get_path ( + // GTK_TREE_MODEL(process_list->list_store), + // &iter))); + process_list->number_of_process++; + + *height = get_cell_height(GTK_TREE_VIEW(process_list->process_list_widget)) + * process_list->number_of_process ; + + + return 0; + +} + +int processlist_remove( ProcessList *process_list, + guint pid, + LttTime *birth) +{ + ProcessInfo Process_Info; + gint *path_indices; + HashedProcessData *hashed_process_data; + GtkTreeIter iter; + + Process_Info.pid = pid; + Process_Info.birth = *birth; + + + if(hashed_process_data = + (HashedProcessData*)g_hash_table_lookup( + process_list->process_hash, + &Process_Info)) + { + gtk_tree_model_get_iter ( + GTK_TREE_MODEL(process_list->list_store), + &iter, + gtk_tree_row_reference_get_path( + (GtkTreeRowReference*)hashed_process_data->row_ref) + ); + + gtk_list_store_remove (process_list->list_store, &iter); + + g_free(hashed_process_data->draw_context->previous->modify_under); + g_free(hashed_process_data->draw_context->previous->modify_middle); + g_free(hashed_process_data->draw_context->previous->modify_over); + g_free(hashed_process_data->draw_context->previous->under); + g_free(hashed_process_data->draw_context->previous->middle); + g_free(hashed_process_data->draw_context->previous->over); + g_free(hashed_process_data->draw_context->previous); + g_free(hashed_process_data->draw_context->current->modify_under); + g_free(hashed_process_data->draw_context->current->modify_middle); + g_free(hashed_process_data->draw_context->current->modify_over); + g_free(hashed_process_data->draw_context->current->under); + g_free(hashed_process_data->draw_context->current->middle); + g_free(hashed_process_data->draw_context->current->over); + g_free(hashed_process_data->draw_context->current); + g_free(hashed_process_data->draw_context); + g_free(hashed_process_data); + + g_hash_table_remove(process_list->process_hash, + &Process_Info); + + process_list->number_of_process--; + + return 0; + } else { + return 1; + } +} + + +guint processlist_get_height(ProcessList *process_list) +{ + return get_cell_height(GTK_TREE_VIEW(process_list->process_list_widget)) + * process_list->number_of_process ; +} + + +gint processlist_get_process_pixels( ProcessList *process_list, + guint pid, LttTime *birth, + guint *y, + guint *height, + HashedProcessData **pm_hashed_process_data) +{ + ProcessInfo Process_Info; + gint *path_indices; + GtkTreePath *tree_path; + HashedProcessData *hashed_process_data = NULL; + + Process_Info.pid = pid; + Process_Info.birth = *birth; + + if(hashed_process_data = + (HashedProcessData*)g_hash_table_lookup( + process_list->process_hash, + &Process_Info)) + { + tree_path = gtk_tree_row_reference_get_path( + hashed_process_data->row_ref); + path_indices = gtk_tree_path_get_indices (tree_path); + + *height = get_cell_height( + GTK_TREE_VIEW(process_list->process_list_widget)); + *y = *height * path_indices[0]; + *pm_hashed_process_data = hashed_process_data; + return 0; + } else { + *pm_hashed_process_data = hashed_process_data; + return 1; + } + +} + + +gint processlist_get_pixels_from_data( ProcessList *process_list, + ProcessInfo *process_info, + HashedProcessData *hashed_process_data, + guint *y, + guint *height) +{ + gint *path_indices; + GtkTreePath *tree_path; + + tree_path = gtk_tree_row_reference_get_path( + hashed_process_data->row_ref); + path_indices = gtk_tree_path_get_indices (tree_path); + + *height = get_cell_height( + GTK_TREE_VIEW(process_list->process_list_widget)); + *y = *height * path_indices[0]; + + return 0; + +} diff --git a/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Process_List.h b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Process_List.h new file mode 100644 index 00000000..d3272160 --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Process_List.h @@ -0,0 +1,75 @@ +#ifndef _PROCESS_LIST_H +#define _PROCESS_LIST_H + +#include +#include +#include +#include "Draw_Item.h" + +/* The process list + * + * Tasks : + * Create a process list + * contains the data for the process list + * tells the height of the process list widget + * provides methods to add/remove process from the list + * note : the sync with drawing is left to the caller. + * provides helper function to convert a process unique identifier to + * pixels (in height). + * + * //FIXME : connect the scrolled window adjustment with the list. + */ + +typedef struct _ProcessInfo { + + guint pid; + LttTime birth; + +} ProcessInfo; + +typedef struct _HashedProcessData { + + GtkTreeRowReference *row_ref; + DrawContext *draw_context; + +} HashedProcessData; + +struct _ProcessList { + + GtkWidget *process_list_widget; + GtkListStore *list_store; + + /* A hash table by PID to speed up process position find in the list */ + GHashTable *process_hash; + + guint number_of_process; +}; + + +typedef struct _ProcessList ProcessList; + +ProcessList *processlist_construct(void); +void processlist_destroy(ProcessList *process_list); +GtkWidget *processlist_get_widget(ProcessList *process_list); + +// out : success (0) and height +int processlist_add(ProcessList *process_list, guint pid, LttTime *birth, + gchar *name, guint *height, HashedProcessData **hashed_process_data); +// out : success (0) and height +int processlist_remove(ProcessList *process_list, guint pid, LttTime *birth); + +guint processlist_get_height(ProcessList *process_list); + +// Returns 0 on success +gint processlist_get_process_pixels(ProcessList *process_list, + guint pid, LttTime *birth, + guint *y, guint *height, + HashedProcessData **hashed_process_data); + +gint processlist_get_pixels_from_data( ProcessList *process_list, + ProcessInfo *process_info, + HashedProcessData *hashed_process_data, + guint *y, + guint *height); + +#endif // _PROCESS_LIST_H diff --git a/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Widget_Callbacks.c.old b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Widget_Callbacks.c.old new file mode 100644 index 00000000..873db1c6 --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/Widget_Callbacks.c.old @@ -0,0 +1,51 @@ +/***************************************************************************** + * Callbacks used for the viewer * + *****************************************************************************/ +void expose_event_cb (GtkWidget *widget, GdkEventExpose *expose, gpointer data) +{ + ControlFlowData *control_flow_data = (ControlFlowData*)data; + + EventRequest *event_request = g_new(sizeof(EventRequest)); + + event_request->control_flow_data = control_flow_data; + + /* Calculate, from pixels in expose, the time interval to get data */ + + get_time_from_pixels(expose->area.x, expose->area.width, + control_flow_data->drawing_Area_Info.width, + &control_flow_data->Begin_Time, &control_flow_data->End_Time, + &event_request->time_begin, &event_request->time_end) + + /* Look in statistics of the trace the processes present during the + * whole time interval _shown on the screen_. Modify the list of + * processes to match it. NOTE : modify, not recreate. If recreation is + * needed,keep a pointer to the currently selected event in the list. + */ + + /* Call the reading API to have events sent to drawing hooks */ + lttv_trace_set_process( control_flow_data->Trace_Set, + Draw_Before_Hooks, + Draw_Event_Hooks, + Draw_After_Hooks, + NULL, //FIXME : filter here + event_request->time_begin, + event_request->time_end); + +} + + +void v_scroll_cb (GtkAdjustment *adjustment, gpointer data) +{ + ControlFlowData *control_flow_data = (ControlFlowData*)data; + GtkTreePath *Tree_Path; + + g_critical("DEBUG : scroll signal, value : %f", adjustment->value); + + //get_test_data((int)adjustment->value, control_flow_data->Num_Visible_Events, + // control_flow_data); + + + +} + + diff --git a/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/guiControlFlow.c.old b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/guiControlFlow.c.old new file mode 100644 index 00000000..5c7961d5 --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/guiControlFlow.c.old @@ -0,0 +1,99 @@ +//FIXME by including ltt.h +#include +typedef time_t ltt_time; + +typedef struct _ltt_time_interval +{ + ltt_time time_begin, time_end; +} ltt_time_interval; + +// ??? + + + /* Setup the hooks */ + Draw_Before_Hooks = lttv_hooks_new(); + Draw_Event_Hooks = lttv_hooks_new(); + Draw_After_Hooks = lttv_hooks_new(); + + lttv_hooks_add(Draw_Before_Hooks, Draw_Before_Hook, NULL); + lttv_hooks_add(Draw_Event_Hooks, Draw_Event_Hook, NULL); + lttv_hooks_add(Draw_After_Hooks, Draw_After_Hook, NULL); + + /* Destroy the hooks */ + + lttv_hooks_destroy(Draw_Before_Hooks); + lttv_hooks_destroy(Draw_Event_Hooks); + lttv_hooks_destroy(Draw_After_Hooks); + + + + +/***************************************************************************** + * Definition of structures * + *****************************************************************************/ + +/* 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; + ltt_time time_begin, time_end; + /* Fill the Events_Context during the initial expose, before calling for + * events. + */ + GArray Events_Context; //FIXME +} EventRequest ; + + + +/***************************************************************************** + * Function prototypes * + *****************************************************************************/ +//! Control Flow Viewer's constructor hook +GtkWidget *hGuiControlFlow(GtkWidget *mw); +//! Control Flow Viewer's constructor +ControlFlowData *GuiControlFlow(void); +//! Control Flow Viewer's destructor +void GuiControlFlow_Destructor(ControlFlowData *control_flow_data); + + +static int Event_Selected_Hook(void *hook_data, void *call_data); + +static lttv_hooks + *Draw_Before_Hooks, + *Draw_Event_Hooks, + *Draw_After_Hooks; + +Draw_Before_Hook(void *hook_data, void *call_data) +Draw_Event_Hook(void *hook_data, void *call_data) +Draw_After_Hook(void *hook_data, void *call_data) + + +//void Tree_V_set_cursor(ControlFlowData *control_flow_data); +//void Tree_V_get_cursor(ControlFlowData *control_flow_data); + +/* Prototype for selection handler callback */ +//static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data); +static void v_scroll_cb (GtkAdjustment *adjustment, gpointer data); +//static void Tree_V_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer data); +//static void Tree_V_size_request_cb (GtkWidget *widget, GtkRequisition *requisition, gpointer data); +//static void Tree_V_cursor_changed_cb (GtkWidget *widget, gpointer data); +//static void Tree_V_move_cursor_cb (GtkWidget *widget, GtkMovementStep arg1, gint arg2, gpointer data); + +static void expose_event_cb (GtkWidget *widget, GdkEventExpose *expose, gpointer data); + +void add_test_process(ControlFlowData *control_flow_data); + +static void get_test_data(guint event_number, guint List_Height, + ControlFlowData *control_flow_data); + +void add_test_data(ControlFlowData *control_flow_data); +void test_draw(ControlFlowData *control_flow_data); + +void drawing_Area_Init(ControlFlowData *control_flow_data); + + +/*\@}*/ diff --git a/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/module.c b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/module.c new file mode 100644 index 00000000..216688fb --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/module.c @@ -0,0 +1,100 @@ +/*! \defgroup guiEvents libguiControlFlow: The GUI ControlFlow display plugin */ +/*\@{*/ + +/*! \file guiControlFlow.c + * \brief Graphical plugin for showing control flow of a trace. + * + * This plugin adds a Control Flow Viewer functionnality to Linux TraceToolkit + * GUI when this plugin is loaded. The init and destroy functions add the + * viewer's insertion menu item and toolbar icon by calling gtkTraceSet's + * API functions. Then, when a viewer's object is created, the constructor + * creates ans register through API functions what is needed to interact + * with the TraceSet window. + * + * This plugin uses the gdk library to draw the events and gtk to interact + * with the user. + * + * Author : Mathieu Desnoyers, June 2003 + */ + +#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) + +#include +#include +#include +#include + +#include "CFV.h" +#include "Event_Hooks.h" + + #include "../icons/hGuiControlFlowInsert.xpm" + +static LttvModule *Main_Win_Module; + + +/** Array containing instanced objects. Used when module is unloaded */ +GSList *g_control_flow_data_list = NULL ; + + + + +/***************************************************************************** + * Functions for module loading/unloading * + *****************************************************************************/ +/** + * plugin's init function + * + * This function initializes the Control Flow Viewer functionnality through the + * gtkTraceSet API. + */ +G_MODULE_EXPORT void init(LttvModule *self, int argc, char *argv[]) { + + Main_Win_Module = lttv_module_require(self, "mainwin", argc, argv); + + if(Main_Win_Module == NULL) + { + g_critical("Can't load Control Flow Viewer : missing mainwin\n"); + return; + } + + g_info("GUI ControlFlow Viewer init()"); + + /* Register the toolbar insert button */ + toolbar_item_reg(hGuiControlFlowInsert_xpm, "Insert Control Flow Viewer", + h_guicontrolflow); + + /* Register the menu item insert entry */ + menu_item_reg("/", "Insert Control Flow Viewer", h_guicontrolflow); + +} + +void destroy_walk(gpointer data, gpointer user_data) +{ + g_info("Walk destroy GUI Control Flow Viewer"); + guicontrolflow_destructor_full((ControlFlowData*)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. + */ +G_MODULE_EXPORT void destroy() { + g_info("GUI Control Flow Viewer destroy()"); + int i; + + g_slist_foreach(g_control_flow_data_list, destroy_walk, NULL ); + + g_slist_free(g_control_flow_data_list); + + /* Unregister the toolbar insert button */ + toolbar_item_unreg(h_guicontrolflow); + + /* Unregister the menu item insert entry */ + menu_item_unreg(h_guicontrolflow); + +} diff --git a/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/test.c b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/test.c new file mode 100644 index 00000000..c326fc5f --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/ControlFlow/guiControlFlow/test.c @@ -0,0 +1,558 @@ + + +static void destroy_cb( GtkWidget *widget, + gpointer data ) +{ + gtk_main_quit (); +} + + + +int main(int argc, char **argv) +{ + GtkWidget *Window; + GtkWidget *CF_Viewer; + GtkWidget *VBox_V; + GtkWidget *HScroll_VC; + ControlFlowData *control_flow_data; + guint ev_sel = 444 ; + /* Horizontal scrollbar and it's adjustment */ + GtkWidget *VScroll_VC; + GtkAdjustment *v_adjust ; + + /* Initialize i18n support */ + gtk_set_locale (); + + /* Initialize the widget set */ + gtk_init (&argc, &argv); + + init(); + + Window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (Window), ("Test Window")); + + g_signal_connect (G_OBJECT (Window), "destroy", + G_CALLBACK (destroy_cb), NULL); + + + VBox_V = gtk_vbox_new(0, 0); + gtk_container_add (GTK_CONTAINER (Window), VBox_V); + + //ListViewer = hGuiEvents(Window); + //gtk_box_pack_start(GTK_BOX(VBox_V), ListViewer, TRUE, TRUE, 0); + + //ListViewer = hGuiEvents(Window); + //gtk_box_pack_start(GTK_BOX(VBox_V), ListViewer, FALSE, TRUE, 0); + + control_flow_data = guicontrolflow(); + CF_Viewer = control_flow_data->scrolled_window; + gtk_box_pack_start(GTK_BOX(VBox_V), CF_Viewer, TRUE, TRUE, 0); + + /* Create horizontal scrollbar and pack it */ + HScroll_VC = gtk_hscrollbar_new(NULL); + gtk_box_pack_start(GTK_BOX(VBox_V), HScroll_VC, FALSE, TRUE, 0); + + + gtk_widget_show (HScroll_VC); + gtk_widget_show (VBox_V); + gtk_widget_show (Window); + + //Event_Selected_Hook(control_flow_data, &ev_sel); + + gtk_main (); + + g_critical("main loop finished"); + + //h_guievents_destructor(ListViewer); + + //g_critical("GuiEvents Destructor finished"); + destroy(); + + return 0; +} + + + +void add_test_process(ControlFlowData *control_flow_data) +{ + GtkTreeIter iter; + int i; + gchar *process[] = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" }; + + for(i=0; inumber_of_process; i++) + { + /* Add a new row to the model */ + gtk_list_store_append (control_flow_data->list_store, &iter); + gtk_list_store_set ( control_flow_data->list_store, &iter, + PROCESS_COLUMN, process[i], + -1); + } + +} + + + + + + +void test_draw(ControlFlowData *control_flow_data) +{ + /* Draw event states using available height, Number of process, cell height + * (don't forget to remove two pixels at beginning and end). + * For horizontal : use width, Time_Begin, Time_End. + * This function calls the reading library to get the draw_hook called + * for the desired period of time. */ + + drawingAreaInfo *drawing_Area_Info = &control_flow_data->drawing_Area_Info; + + +} + +#ifdef DEBUG +void test_draw() { + gint cell_height = get_cell_height(GTK_TREE_VIEW(control_flow_data->process_list_widget)); + GdkGC *GC = gdk_gc_new(widget->window); + GdkColor color = CF_Colors[GREEN]; + + gdk_color_alloc (gdk_colormap_get_system () , &color); + + g_critical("expose"); + + /* When redrawing, use widget->allocation.width to get the width of + * drawable area. */ + control_flow_data->drawing_Area_Info.width = widget->allocation.width; + + test_draw(control_flow_data); + + gdk_gc_copy(GC,widget->style->white_gc); + gdk_gc_set_foreground(GC,&color); + + //gdk_draw_arc (widget->window, + // widget->style->fg_gc[GTK_WIDGET_STATE (widget)], + // TRUE, + // //0, 0, widget->allocation.width, widget->allocation.height, + // 0, 0, widget->allocation.width, + // control_flow_data->drawing_Area_Info.height, + // 0, 64 * 360); + + + //drawing_Area_Init(control_flow_data); + + // 2 pixels for the box around the drawing area, 1 pixel for off-by-one + // (starting from 0) + //gdk_gc_copy (&GC, widget->style->fg_gc[GTK_WIDGET_STATE (widget)]); + + gdk_gc_set_line_attributes(GC,12, GDK_LINE_SOLID, GDK_CAP_NOT_LAST,GDK_JOIN_MITER); + + gdk_draw_line (widget->window, + GC, + 0, (cell_height-1)/2, + widget->allocation.width, (cell_height-1)/2); + + color = CF_Colors[BLUE]; + + gdk_color_alloc (gdk_colormap_get_system () , &color); + + gdk_gc_set_foreground(GC,&color); + + + gdk_gc_set_line_attributes(GC,3, GDK_LINE_SOLID, GDK_CAP_NOT_LAST,GDK_JOIN_MITER); + + gdk_draw_line (widget->window, + GC, + 0, (cell_height-1)/2, + widget->allocation.width,(cell_height-1)/2); + + + + + + + g_object_unref(GC); + + //gdk_colormap_alloc_colors(gdk_colormap_get_system(), TRUE, + + //gdk_gc_set_line_attributes(GC,5, GDK_LINE_SOLID, GDK_CAP_NOT_LAST,GDK_JOIN_MITER); + //gdk_gc_set_foreground(GC, + + //gdk_draw_line (widget->window, + // GC, + // 0, (2*cell_height)-2-1, + // 50, (2*cell_height)-2-1); + +} +#endif //DEBUG + + +/* Event_Hook.c tests */ + +void test_draw_item(Drawing_t *drawing, + GdkPixmap *pixmap) +{ + PropertiesIcon properties_icon; + DrawContext draw_context; + + DrawInfo current, previous; + ItemInfo over, middle, under, modify_over, modify_middle, modify_under; + + int i=0,j=0; + + //for(i=0; i<1024;i=i+15) + { + // for(j=0;j<768;j=j+15) + { + over.x = i; + over.y = j; + + current.modify_over = &over; + + draw_context.drawable = pixmap; + draw_context.gc = drawing->drawing_area->style->black_gc; + + draw_context.current = ¤t; + draw_context.previous = NULL; + + properties_icon.icon_name = g_new(char, MAX_PATH_LEN); + strncpy(properties_icon.icon_name, + "/home/compudj/local/share/LinuxTraceToolkit/pixmaps/mini-display.xpm", + MAX_PATH_LEN); + properties_icon.width = -1; + properties_icon.height = -1; + properties_icon.position = OVER; + draw_icon(&properties_icon, &draw_context); + g_free(properties_icon.icon_name); + } + } + +} + +#ifdef NOTUSE +/* NOTE : no drawing data should be sent there, since the drawing widget + * has not been initialized */ +void send_test_drawing(ProcessList *process_list, + Drawing_t *drawing, + GdkPixmap *pixmap, + gint x, gint y, // y not used here? + gint width, + gint height) // height won't be used here ? +{ + int i,j; + ProcessInfo Process_Info = {10000, 12000, 55600}; + //ProcessInfo Process_Info = {156, 14000, 55500}; + GtkTreeRowReference *row_ref; + PangoContext *context; + PangoLayout *layout; + PangoFontDescription *FontDesc;// = pango_font_description_new(); + gint Font_Size; + + //icon + //GdkBitmap *mask = g_new(GdkBitmap, 1); + //GdkPixmap *icon_pixmap = g_new(GdkPixmap, 1); + GdkGC * gc; + // rectangle + GdkColor color = { 0, 0xffff, 0x0000, 0x0000 }; + + gc = gdk_gc_new(pixmap); + /* Sent text data */ + layout = gtk_widget_create_pango_layout(drawing->drawing_area, + NULL); + context = pango_layout_get_context(layout); + FontDesc = pango_context_get_font_description(context); + Font_Size = pango_font_description_get_size(FontDesc); + pango_font_description_set_size(FontDesc, Font_Size-3*PANGO_SCALE); + + + + + LttTime birth; + birth.tv_sec = 12000; + birth.tv_nsec = 55500; + g_info("we have : x : %u, y : %u, width : %u, height : %u", x, y, width, height); + processlist_get_process_pixels(process_list, + 1, + &birth, + &y, + &height); + + g_info("we draw : x : %u, y : %u, width : %u, height : %u", x, y, width, height); + drawing_draw_line( + drawing, pixmap, x, + y+(height/2), x + width, y+(height/2), + drawing->drawing_area->style->black_gc); + + pango_layout_set_text(layout, "Test", -1); + gdk_draw_layout(pixmap, drawing->drawing_area->style->black_gc, + 0, y+height, layout); + + birth.tv_sec = 14000; + birth.tv_nsec = 55500; + + processlist_get_process_pixels(process_list, + 156, + &birth, + &y, + &height); + + + drawing_draw_line( + drawing, pixmap, x, + y+(height/2), x + width, y+(height/2), + drawing->drawing_area->style->black_gc); + + g_info("y : %u, height : %u", y, height); + + + + birth.tv_sec = 12000; + birth.tv_nsec = 55700; + + processlist_get_process_pixels(process_list, + 10, + &birth, + &y, + &height); + + /* Draw rectangle (background color) */ + gdk_gc_copy(gc, drawing->drawing_area->style->black_gc); + gdk_gc_set_rgb_fg_color(gc, &color); + gdk_draw_rectangle(pixmap, gc, + TRUE, + x, y, width, height); + + drawing_draw_line( + drawing, pixmap, x, + y+(height/2), x + width, y+(height/2), + drawing->drawing_area->style->black_gc); + + + /* Draw arc */ + gdk_draw_arc(pixmap, drawing->drawing_area->style->black_gc, + TRUE, 100, y, height/2, height/2, 0, 360*64); + + g_info("y : %u, height : %u", y, height); + + for(i=0; i<10; i++) + { + birth.tv_sec = i*12000; + birth.tv_nsec = i*55700; + + processlist_get_process_pixels(process_list, + i, + &birth, + &y, + &height); + + + drawing_draw_line( + drawing, pixmap, x, + y+(height/2), x + width, y+(height/2), + drawing->drawing_area->style->black_gc); + + g_critical("y : %u, height : %u", y, height); + + } + + birth.tv_sec = 12000; + birth.tv_nsec = 55600; + + processlist_get_process_pixels(process_list, + 10, + &birth, + &y, + &height); + + + drawing_draw_line( + drawing, pixmap, x, + y+(height/2), x + width, y+(height/2), + drawing->drawing_area->style->black_gc); + + g_info("y : %u, height : %u", y, height); + + + /* IMPORTANT : This action uses the cpu heavily! */ + //icon_pixmap = gdk_pixmap_create_from_xpm(pixmap, &mask, NULL, +// "/home/compudj/local/share/LinuxTraceToolkit/pixmaps/move_message.xpm"); + // "/home/compudj/local/share/LinuxTraceToolkit/pixmaps/mini-display.xpm"); + + // gdk_gc_set_clip_mask(drawing->drawing_area->style->black_gc, mask); + +// for(i=x;idrawing_area->style->black_gc); +// gdk_gc_set_clip_origin(drawing->drawing_area->style->black_gc, i, j); +// gdk_draw_drawable(pixmap, +// drawing->drawing_area->style->black_gc, +// icon_pixmap, +// 0, 0, i, j, -1, -1); + +// } +// } + + test_draw_item(drawing,pixmap); + + //gdk_gc_set_clip_origin(drawing->drawing_area->style->black_gc, 0, 0); + //gdk_gc_set_clip_mask(drawing->drawing_area->style->black_gc, NULL); + + //g_free(icon_pixmap); + //g_free(mask); + + + + + + + pango_font_description_set_size(FontDesc, Font_Size); + g_object_unref(layout); + g_free(gc); +} + +void send_test_process(ProcessList *process_list, Drawing_t *drawing) +{ + guint height, y; + int i; + ProcessInfo Process_Info = {10000, 12000, 55600}; + //ProcessInfo Process_Info = {156, 14000, 55500}; + GtkTreeRowReference *row_ref; + + LttTime birth; + + if(process_list->Test_Process_Sent) return; + + birth.tv_sec = 12000; + birth.tv_nsec = 55500; + + processlist_add(process_list, + 1, + &birth, + &y); + processlist_get_process_pixels(process_list, + 1, + &birth, + &y, + &height); + drawing_insert_square( drawing, y, height); + + //g_critical("y : %u, height : %u", y, height); + + birth.tv_sec = 14000; + birth.tv_nsec = 55500; + + processlist_add(process_list, + 156, + &birth, + &y); + processlist_get_process_pixels(process_list, + 156, + &birth, + &y, + &height); + drawing_insert_square( drawing, y, height); + + //g_critical("y : %u, height : %u", y, height); + + birth.tv_sec = 12000; + birth.tv_nsec = 55700; + + processlist_add(process_list, + 10, + &birth, + &height); + processlist_get_process_pixels(process_list, + 10, + &birth, + &y, + &height); + drawing_insert_square( drawing, y, height); + + //g_critical("y : %u, height : %u", y, height); + + //drawing_insert_square( drawing, height, 5); + + for(i=0; i<10; i++) + { + birth.tv_sec = i*12000; + birth.tv_nsec = i*55700; + + processlist_add(process_list, + i, + &birth, + &height); + processlist_get_process_pixels(process_list, + i, + &birth, + &y, + &height); + drawing_insert_square( drawing, y, height); + + // g_critical("y : %u, height : %u", y, height); + + } + //g_critical("height : %u", height); + + birth.tv_sec = 12000; + birth.tv_nsec = 55600; + + processlist_add(process_list, + 10, + &birth, + &y); + processlist_get_process_pixels(process_list, + 10, + &birth, + &y, + &height); + drawing_insert_square( drawing, y, height); + + //g_critical("y : %u, height : %u", y, height); + + processlist_add(process_list, + 10000, + &birth, + &height); + processlist_get_process_pixels(process_list, + 10000, + &birth, + &y, + &height); + drawing_insert_square( drawing, y, height); + + //g_critical("y : %u, height : %u", y, height); + + //drawing_insert_square( drawing, height, 5); + //g_critical("height : %u", height); + + + processlist_get_process_pixels(process_list, + 10000, + &birth, + &y, &height); + processlist_remove( process_list, + 10000, + &birth); + + drawing_remove_square( drawing, y, height); + + if(row_ref = + (GtkTreeRowReference*)g_hash_table_lookup( + process_list->process_hash, + &Process_Info)) + { + g_critical("key found"); + g_critical("position in the list : %s", + gtk_tree_path_to_string ( + gtk_tree_row_reference_get_path( + (GtkTreeRowReference*)row_ref) + )); + + } + + process_list->Test_Process_Sent = TRUE; + +} +#endif//NOTUSE + diff --git a/ltt/branches/poly/lttv/modules/gui/DetailedEvents/guiEvents.c b/ltt/branches/poly/lttv/modules/gui/DetailedEvents/guiEvents.c new file mode 100644 index 00000000..feeb029f --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/DetailedEvents/guiEvents.c @@ -0,0 +1,1872 @@ +//*! \defgroup GuiEvents libGuiEvents: The GUI Events display plugin */ +/*\@{*/ + +/*! \file GuiEvents.c + * \brief Graphical plugin for showing events. + * + * This plugin lists all the events contained in the current time interval + * in a list. + * + * This plugin adds a Events Viewer functionnality to Linux TraceToolkit + * GUI when this plugin is loaded. The init and destroy functions add the + * viewer's insertion menu item and toolbar icon by calling gtkTraceSet's + * API functions. Then, when a viewer's object is created, the constructor + * creates ans register through API functions what is needed to interact + * with the TraceSet window. + * + * Authors : Mathieu Desnoyers and XangXiu Yang, June to December 2003 + * Inspired from original LTT, made by Karim Yaghmour + */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#include "mw_api.h" +#include "gtktreeprivate.h" + +#include "icons/hGuiEventsInsert.xpm" + + +static LttvHooks *before_event; + +/** Array containing instanced objects. Used when module is unloaded */ +static GSList *g_event_viewer_data_list = NULL ; + +typedef struct _RawTraceData{ + unsigned cpu_id; + char * event_name; + LttTime time; + int pid; + unsigned entry_length; + char * event_description; + LttEventPosition *ep; +} RawTraceData; + +#define RESERVE_BIG_SIZE 1000 +#define RESERVE_SMALL_SIZE 100 +#define RESERVE_SMALL_SIZE_SQUARE RESERVE_SMALL_SIZE*RESERVE_SMALL_SIZE +#define RESERVE_SMALL_SIZE_CUBE RESERVE_SMALL_SIZE*RESERVE_SMALL_SIZE_SQUARE + +typedef enum _ScrollDirection{ + SCROLL_STEP_UP, + SCROLL_STEP_DOWN, + SCROLL_PAGE_UP, + SCROLL_PAGE_DOWN, + SCROLL_JUMP, + SCROLL_NONE +} ScrollDirection; + +typedef struct _EventViewerData { + + MainWindow * mw; + TimeWindow time_window; + LttTime current_time; + LttvHooks * before_event_hooks; + + gboolean append; //prepend or append item + GQueue * raw_trace_data_queue; //buf to contain raw trace data + GQueue * raw_trace_data_queue_tmp; //tmp buf to contain raw data + unsigned current_event_index; + double previous_value; //value of the slide + TimeInterval time_span; + unsigned start_event_index; //the first event shown in the window + unsigned end_event_index; //the last event shown in the window + unsigned size; //maxi number of events loaded when instance the viewer + gboolean shown; //indicate if event detail is shown or not + gboolean current_time_updated; + char * filter_key; + + //scroll window containing Tree View + GtkWidget * scroll_win; + + /* Model containing list data */ + GtkListStore *store_m; + + GtkWidget *hbox_v; + /* Widget to display the data in a columned list */ + GtkWidget *tree_v; + GtkAdjustment *vtree_adjust_c ; + + /* Vertical scrollbar and it's adjustment */ + GtkWidget *vscroll_vc; + GtkAdjustment *vadjust_c ; + + /* Selection handler */ + GtkTreeSelection *select_c; + + guint num_visible_events; + guint first_event, last_event; + + /* TEST DATA, TO BE READ FROM THE TRACE */ + gint number_of_events ; + guint currently_selected_event ; + gboolean selected_event ; + +} EventViewerData ; + +/** hook functions for update time interval, current time ... */ +gboolean update_time_window(void * hook_data, void * call_data); +gboolean update_current_time(void * hook_data, void * call_data); +gboolean show_event_detail(void * hook_data, void * call_data); +gboolean traceset_changed(void * hook_data, void * call_data); +void remove_item_from_queue(GQueue * q, gboolean fromHead); +void remove_all_items_from_queue(GQueue * q); +void add_context_hooks(EventViewerData * event_viewer_data, + LttvTracesetContext * tsc); +void remove_context_hooks(EventViewerData * event_viewer_data, + LttvTracesetContext * tsc); + +//! Event Viewer's constructor hook +GtkWidget *h_gui_events(MainWindow *parent_window, LttvTracesetSelector * s, char* key); +//! Event Viewer's constructor +EventViewerData *gui_events(MainWindow *parent_window, LttvTracesetSelector *s, char *key); +//! Event Viewer's destructor +void gui_events_destructor(EventViewerData *event_viewer_data); +void gui_events_free(EventViewerData *event_viewer_data); + +static int event_selected_hook(void *hook_data, void *call_data); + +void tree_v_set_cursor(EventViewerData *event_viewer_data); +void tree_v_get_cursor(EventViewerData *event_viewer_data); + +/* Prototype for selection handler callback */ +static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data); +static void v_scroll_cb (GtkAdjustment *adjustment, gpointer data); +static void tree_v_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer data); +static void tree_v_size_request_cb (GtkWidget *widget, GtkRequisition *requisition, gpointer data); +static void tree_v_cursor_changed_cb (GtkWidget *widget, gpointer data); +static void tree_v_move_cursor_cb (GtkWidget *widget, GtkMovementStep arg1, gint arg2, gpointer data); +static void tree_v_grab_focus(GtkWidget *widget, gpointer data); + + +static void get_test_data(double time, guint list_height, + EventViewerData *event_viewer_data); + +void add_test_data(EventViewerData *event_viewer_data); + +static void update_raw_data_array(EventViewerData* event_viewer_data, unsigned size); + +static void get_events(EventViewerData* event_viewer_data, LttTime start, + LttTime end, unsigned max_num_events, unsigned * real_num_events); +static gboolean parse_event(void *hook_data, void *call_data); + +static LttvModule *main_win_module; + +/** + * plugin's init function + * + * This function initializes the Event Viewer functionnality through the + * gtkTraceSet API. + */ +G_MODULE_EXPORT void init(LttvModule *self, int argc, char *argv[]) { + + main_win_module = lttv_module_require(self, "mainwin", argc, argv); + + if(main_win_module == NULL){ + g_critical("Can't load Control Flow Viewer : missing mainwin\n"); + return; + } + + /* Register the toolbar insert button */ + toolbar_item_reg(hGuiEventsInsert_xpm, "Insert Event Viewer", h_gui_events); + + /* Register the menu item insert entry */ + menu_item_reg("/", "Insert Event Viewer", h_gui_events); + +} + +void event_destroy_walk(gpointer data, gpointer user_data) +{ + gui_events_destructor((EventViewerData*)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. + */ +G_MODULE_EXPORT void destroy() { + int i; + + EventViewerData *event_viewer_data; + + if(g_event_viewer_data_list){ + g_slist_foreach(g_event_viewer_data_list, event_destroy_walk, NULL ); + g_slist_free(g_event_viewer_data_list); + } + + /* Unregister the toolbar insert button */ + toolbar_item_unreg(h_gui_events); + + /* Unregister the menu item insert entry */ + menu_item_unreg(h_gui_events); +} + +/* Enumeration of the columns */ +enum +{ + CPUID_COLUMN, + EVENT_COLUMN, + TIME_COLUMN, + PID_COLUMN, + ENTRY_LEN_COLUMN, + EVENT_DESCR_COLUMN, + N_COLUMNS +}; + + +/** + * Event Viewer's constructor hook + * + * This constructor is given as a parameter to the menuitem and toolbar button + * registration. It creates the list. + * @param parent_window A pointer to the parent window. + * @return The widget created. + */ +GtkWidget * +h_gui_events(MainWindow * parent_window, LttvTracesetSelector * s, char* key) +{ + EventViewerData* event_viewer_data = gui_events(parent_window, s, key) ; + + if(event_viewer_data) + return event_viewer_data->hbox_v; + else return NULL; + +} + +/** + * Event Viewer's constructor + * + * This constructor is used to create EventViewerData data structure. + * @return The Event viewer data created. + */ +EventViewerData * +gui_events(MainWindow *parent_window, LttvTracesetSelector * s,char* key ) +{ + LttTime start, end; + GtkTreeViewColumn *column; + GtkCellRenderer *renderer; + EventViewerData* event_viewer_data = g_new(EventViewerData,1) ; + RawTraceData * data; + + event_viewer_data->mw = parent_window; + get_time_window(event_viewer_data->mw, &event_viewer_data->time_window); + get_current_time(event_viewer_data->mw, &event_viewer_data->current_time); + + event_viewer_data->before_event_hooks = lttv_hooks_new(); + lttv_hooks_add(event_viewer_data->before_event_hooks, parse_event, event_viewer_data); + + event_viewer_data->raw_trace_data_queue = g_queue_new(); + event_viewer_data->raw_trace_data_queue_tmp = g_queue_new(); + + reg_update_time_window(update_time_window,event_viewer_data, event_viewer_data->mw); + reg_update_current_time(update_current_time,event_viewer_data, event_viewer_data->mw); + reg_show_viewer(show_event_detail,event_viewer_data, event_viewer_data->mw); + reg_update_traceset(traceset_changed,event_viewer_data, event_viewer_data->mw); + + event_viewer_data->scroll_win = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show ( event_viewer_data->scroll_win); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(event_viewer_data->scroll_win), + GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER); + + /* TEST DATA, TO BE READ FROM THE TRACE */ + event_viewer_data->currently_selected_event = FALSE ; + event_viewer_data->selected_event = 0; + + /* Create a model for storing the data list */ + event_viewer_data->store_m = gtk_list_store_new ( + N_COLUMNS, /* Total number of columns */ + G_TYPE_INT, /* CPUID */ + G_TYPE_STRING, /* Event */ + G_TYPE_UINT64, /* Time */ + G_TYPE_INT, /* PID */ + G_TYPE_INT, /* Entry length */ + G_TYPE_STRING); /* Event's description */ + + /* Create the viewer widget for the columned list */ + event_viewer_data->tree_v = gtk_tree_view_new_with_model (GTK_TREE_MODEL (event_viewer_data->store_m)); + + g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "size-allocate", + G_CALLBACK (tree_v_size_allocate_cb), + event_viewer_data); + g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "size-request", + G_CALLBACK (tree_v_size_request_cb), + event_viewer_data); + + g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "cursor-changed", + G_CALLBACK (tree_v_cursor_changed_cb), + event_viewer_data); + + g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "move-cursor", + G_CALLBACK (tree_v_move_cursor_cb), + event_viewer_data); + + g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "grab-focus", + G_CALLBACK (tree_v_grab_focus), + event_viewer_data); + + // Use on each column! + //gtk_tree_view_column_set_sizing(event_viewer_data->tree_v, GTK_TREE_VIEW_COLUMN_FIXED); + + /* The view now holds a reference. We can get rid of our own + * reference */ + g_object_unref (G_OBJECT (event_viewer_data->store_m)); + + + /* Create a column, associating the "text" attribute of the + * cell_renderer to the first column of the model */ + /* Columns alignment : 0.0 : Left 0.5 : Center 1.0 : Right */ + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ("CPUID", + renderer, + "text", CPUID_COLUMN, + NULL); + gtk_tree_view_column_set_alignment (column, 0.0); + gtk_tree_view_column_set_fixed_width (column, 45); + gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column); + + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ("Event", + renderer, + "text", EVENT_COLUMN, + NULL); + gtk_tree_view_column_set_alignment (column, 0.0); + gtk_tree_view_column_set_fixed_width (column, 120); + gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column); + + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ("Time", + renderer, + "text", TIME_COLUMN, + NULL); + gtk_tree_view_column_set_alignment (column, 1.0); + gtk_tree_view_column_set_fixed_width (column, 120); + gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column); + + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ("PID", + renderer, + "text", PID_COLUMN, + NULL); + gtk_tree_view_column_set_alignment (column, 1.0); + gtk_tree_view_column_set_fixed_width (column, 45); + gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column); + + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ("Entry Length", + renderer, + "text", ENTRY_LEN_COLUMN, + NULL); + gtk_tree_view_column_set_alignment (column, 1.0); + gtk_tree_view_column_set_fixed_width (column, 60); + gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column); + + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ("Event's Description", + renderer, + "text", EVENT_DESCR_COLUMN, + NULL); + gtk_tree_view_column_set_alignment (column, 0.0); + gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column); + + + /* Setup the selection handler */ + event_viewer_data->select_c = gtk_tree_view_get_selection (GTK_TREE_VIEW (event_viewer_data->tree_v)); + gtk_tree_selection_set_mode (event_viewer_data->select_c, GTK_SELECTION_SINGLE); + g_signal_connect (G_OBJECT (event_viewer_data->select_c), "changed", + G_CALLBACK (tree_selection_changed_cb), + event_viewer_data); + + gtk_container_add (GTK_CONTAINER (event_viewer_data->scroll_win), event_viewer_data->tree_v); + + event_viewer_data->hbox_v = gtk_hbox_new(0, 0); + gtk_box_pack_start(GTK_BOX(event_viewer_data->hbox_v), event_viewer_data->scroll_win, TRUE, TRUE, 0); + + /* Create vertical scrollbar and pack it */ + event_viewer_data->vscroll_vc = gtk_vscrollbar_new(NULL); + gtk_range_set_update_policy (GTK_RANGE(event_viewer_data->vscroll_vc), + GTK_UPDATE_CONTINUOUS); + // Changed by MD : more user friendly :) + //GTK_UPDATE_DISCONTINUOUS); + gtk_box_pack_start(GTK_BOX(event_viewer_data->hbox_v), event_viewer_data->vscroll_vc, FALSE, TRUE, 0); + + /* Get the vertical scrollbar's adjustment */ + event_viewer_data->vadjust_c = gtk_range_get_adjustment(GTK_RANGE(event_viewer_data->vscroll_vc)); + event_viewer_data->vtree_adjust_c = gtk_tree_view_get_vadjustment( + GTK_TREE_VIEW (event_viewer_data->tree_v)); + + g_signal_connect (G_OBJECT (event_viewer_data->vadjust_c), "value-changed", + G_CALLBACK (v_scroll_cb), + event_viewer_data); + /* Set the upper bound to the last event number */ + event_viewer_data->previous_value = 0; + event_viewer_data->vadjust_c->lower = 0.0; + //event_viewer_data->vadjust_c->upper = event_viewer_data->number_of_events; + event_viewer_data->vadjust_c->value = 0.0; + event_viewer_data->vadjust_c->step_increment = 1.0; + event_viewer_data->vadjust_c->page_increment = 2.0; + // event_viewer_data->vtree_adjust_c->upper; + event_viewer_data->vadjust_c->page_size = 2.0; + // event_viewer_data->vtree_adjust_c->upper; + /* Raw event trace */ + gtk_widget_show(event_viewer_data->hbox_v); + gtk_widget_show(event_viewer_data->tree_v); + gtk_widget_show(event_viewer_data->vscroll_vc); + + /* Add the object's information to the module's array */ + g_event_viewer_data_list = g_slist_append(g_event_viewer_data_list, event_viewer_data); + + event_viewer_data->first_event = -1 ; + event_viewer_data->last_event = 0 ; + + event_viewer_data->num_visible_events = 1; + + //get the life span of the traceset and set the upper of the scroll bar + get_traceset_time_span(event_viewer_data->mw, &event_viewer_data->time_span); + + start = ltt_time_sub(event_viewer_data->time_span.endTime, event_viewer_data->time_span.startTime); + event_viewer_data->vadjust_c->upper = ltt_time_to_double(start) * NANOSECONDS_PER_SECOND; + + event_viewer_data->append = TRUE; + + event_viewer_data->start_event_index = 0; + event_viewer_data->end_event_index = event_viewer_data->num_visible_events - 1; + + /* Set the Selected Event */ + // tree_v_set_cursor(event_viewer_data); + + event_viewer_data->shown = FALSE; + event_viewer_data->current_time_updated = FALSE; + event_viewer_data->size = RESERVE_SMALL_SIZE; + g_object_set_data( + G_OBJECT(event_viewer_data->hbox_v), + MAX_NUMBER_EVENT, + &event_viewer_data->size); + + g_object_set_data( + G_OBJECT(event_viewer_data->hbox_v), + TRACESET_TIME_SPAN, + &event_viewer_data->time_span); + + event_viewer_data->filter_key = g_strdup(key); + g_object_set_data( + G_OBJECT(event_viewer_data->hbox_v), + event_viewer_data->filter_key, + s); + + g_object_set_data_full( + G_OBJECT(event_viewer_data->hbox_v), + "event_viewer_data", + event_viewer_data, + (GDestroyNotify)gui_events_free); + + return event_viewer_data; +} + +void tree_v_set_cursor(EventViewerData *event_viewer_data) +{ + GtkTreePath *path; + + if(event_viewer_data->selected_event && event_viewer_data->first_event != -1) + { + // gtk_adjustment_set_value(event_viewer_data->vadjust_c, + // event_viewer_data->currently_selected_event); + + path = gtk_tree_path_new_from_indices( + event_viewer_data->currently_selected_event- + event_viewer_data->first_event, + -1); + + gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE); + gtk_tree_path_free(path); + } +} + +void tree_v_get_cursor(EventViewerData *event_viewer_data) +{ + GtkTreePath *path; + gint *indices; + + gtk_tree_view_get_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), &path, NULL); + indices = gtk_tree_path_get_indices(path); + + if(indices != NULL) + { + event_viewer_data->selected_event = TRUE; + event_viewer_data->currently_selected_event = + event_viewer_data->first_event + indices[0]; + + } else { + event_viewer_data->selected_event = FALSE; + event_viewer_data->currently_selected_event = 0; + } + + gtk_tree_path_free(path); + +} + + + +void tree_v_move_cursor_cb (GtkWidget *widget, GtkMovementStep arg1, gint arg2, gpointer data) +{ + GtkTreePath *path; // = gtk_tree_path_new(); + gint *indices; + gdouble value; + EventViewerData *event_viewer_data = (EventViewerData*)data; + + gtk_tree_view_get_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), &path, NULL); + if(path == NULL) + { + /* No prior cursor, put it at beginning of page and let the execution do */ + path = gtk_tree_path_new_from_indices(0, -1); + gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE); + } + + indices = gtk_tree_path_get_indices(path); + + value = gtk_adjustment_get_value(event_viewer_data->vadjust_c); + + if(arg1 == GTK_MOVEMENT_DISPLAY_LINES) + { + /* Move one line */ + if(arg2 == 1) + { + /* move one line down */ + if(indices[0] == event_viewer_data->num_visible_events - 1) + { + if(value + event_viewer_data->num_visible_events <= + event_viewer_data->number_of_events -1) + { + event_viewer_data->currently_selected_event += 1; + // gtk_adjustment_set_value(event_viewer_data->vadjust_c, value+1); + //gtk_tree_path_free(path); + //path = gtk_tree_path_new_from_indices(event_viewer_data->num_visible_events-1, -1); + //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE); + g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor"); + } + } + } else { + /* Move one line up */ + if(indices[0] == 0) + { + if(value - 1 >= 0 ) + { + event_viewer_data->currently_selected_event -= 1; + // gtk_adjustment_set_value(event_viewer_data->vadjust_c, value-1); + //gtk_tree_path_free(path); + //path = gtk_tree_path_new_from_indices(0, -1); + //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE); + g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor"); + } + + } + } + + } + + if(arg1 == GTK_MOVEMENT_PAGES) + { + /* Move one page */ + if(arg2 == 1) + { + if(event_viewer_data->num_visible_events == 1) + value += 1 ; + /* move one page down */ + if(value + event_viewer_data->num_visible_events-1 <= + event_viewer_data->number_of_events ) + { + event_viewer_data->currently_selected_event += event_viewer_data->num_visible_events-1; + // gtk_adjustment_set_value(event_viewer_data->vadjust_c, + // value+(event_viewer_data->num_visible_events-1)); + //gtk_tree_path_free(path); + //path = gtk_tree_path_new_from_indices(0, -1); + //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE); + g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor"); + } + } else { + /* Move one page up */ + if(event_viewer_data->num_visible_events == 1) + value -= 1 ; + + if(indices[0] < event_viewer_data->num_visible_events - 2 ) + { + if(value - (event_viewer_data->num_visible_events-1) >= 0) + { + event_viewer_data->currently_selected_event -= event_viewer_data->num_visible_events-1; + + // gtk_adjustment_set_value(event_viewer_data->vadjust_c, + // value-(event_viewer_data->num_visible_events-1)); + //gtk_tree_path_free(path); + //path = gtk_tree_path_new_from_indices(0, -1); + //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE); + g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor"); + + } else { + /* Go to first Event */ + event_viewer_data->currently_selected_event == 0 ; + // gtk_adjustment_set_value(event_viewer_data->vadjust_c, + // 0); + //gtk_tree_path_free(path); + //path = gtk_tree_path_new_from_indices(0, -1); + //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE); + g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor"); + + } + } + + } + + } + + if(arg1 == GTK_MOVEMENT_BUFFER_ENDS) + { + /* Move to the ends of the buffer */ + if(arg2 == 1) + { + /* move end of buffer */ + event_viewer_data->currently_selected_event = event_viewer_data->number_of_events-1 ; + // gtk_adjustment_set_value(event_viewer_data->vadjust_c, + // event_viewer_data->number_of_events - + // event_viewer_data->num_visible_events); + //gtk_tree_path_free(path); + //path = gtk_tree_path_new_from_indices(event_viewer_data->num_visible_events-1, -1); + //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE); + g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor"); + } else { + /* Move beginning of buffer */ + event_viewer_data->currently_selected_event = 0 ; + // gtk_adjustment_set_value(event_viewer_data->vadjust_c, 0); + //gtk_tree_path_free(path); + //path = gtk_tree_path_new_from_indices(0, -1); + //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE); + g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor"); + } + + } + + + gtk_tree_path_free(path); +} + +void tree_v_cursor_changed_cb (GtkWidget *widget, gpointer data) +{ + EventViewerData *event_viewer_data = (EventViewerData*) data; + LttTime ltt_time; + guint64 time; + GtkTreeIter iter; + GtkTreeModel* model = GTK_TREE_MODEL(event_viewer_data->store_m); + GtkTreePath *path; + + /* On cursor change, modify the currently selected event by calling + * the right API function */ + tree_v_get_cursor(event_viewer_data); + + gtk_tree_view_get_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), &path, NULL); + if(gtk_tree_model_get_iter(model,&iter,path)){ + gtk_tree_model_get(model, &iter, TIME_COLUMN, &time, -1); + ltt_time.tv_sec = time / NANOSECONDS_PER_SECOND; + ltt_time.tv_nsec = time % NANOSECONDS_PER_SECOND; + + if(ltt_time.tv_sec != event_viewer_data->current_time.tv_sec || + ltt_time.tv_nsec != event_viewer_data->current_time.tv_nsec){ + event_viewer_data->current_time_updated = TRUE; + set_current_time(event_viewer_data->mw,<t_time); + } + }else{ + g_warning("Can not get iter\n"); + } + +} + + +void v_scroll_cb (GtkAdjustment *adjustment, gpointer data) +{ + EventViewerData *event_viewer_data = (EventViewerData*)data; + GtkTreePath *tree_path; + + get_test_data(adjustment->value, event_viewer_data->num_visible_events, + event_viewer_data); + + + if(event_viewer_data->currently_selected_event + >= event_viewer_data->first_event + && + event_viewer_data->currently_selected_event + <= event_viewer_data->last_event + && + event_viewer_data->selected_event) + { + + tree_path = gtk_tree_path_new_from_indices( + event_viewer_data->currently_selected_event- + event_viewer_data->first_event, + -1); + + // gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), tree_path, + // NULL, FALSE); + gtk_tree_path_free(tree_path); + } + + +} + +gint get_cell_height(GtkTreeView *TreeView) +{ + gint height, width; + GtkTreeViewColumn *column = gtk_tree_view_get_column(TreeView, 0); + GList *Render_List = gtk_tree_view_column_get_cell_renderers(column); + GtkCellRenderer *renderer = g_list_first(Render_List)->data; + + gtk_tree_view_column_cell_get_size(column, NULL, NULL, NULL, NULL, &height); + + return height; +} + +void tree_v_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer data) +{ + EventViewerData *event_viewer_data = (EventViewerData*)data; + gint cell_height = get_cell_height(GTK_TREE_VIEW(event_viewer_data->tree_v)); + gint last_num_visible_events = event_viewer_data->num_visible_events; + gdouble exact_num_visible; + + exact_num_visible = ( alloc->height - + TREE_VIEW_HEADER_HEIGHT (GTK_TREE_VIEW(event_viewer_data->tree_v)) ) + / (double)cell_height ; + + event_viewer_data->num_visible_events = ceil(exact_num_visible) ; + +/* + event_viewer_data->vadjust_c->page_increment = + floor(exact_num_visible); + event_viewer_data->vadjust_c->page_size = + floor(exact_num_visible); +*/ + + if(event_viewer_data->num_visible_events != last_num_visible_events) + { + get_test_data(event_viewer_data->vadjust_c->value, + event_viewer_data->num_visible_events, + event_viewer_data); + } + + +} + +void tree_v_size_request_cb (GtkWidget *widget, GtkRequisition *requisition, gpointer data) +{ + gint h; + EventViewerData *event_viewer_data = (EventViewerData*)data; + gint cell_height = get_cell_height(GTK_TREE_VIEW(event_viewer_data->tree_v)); + + h = cell_height + TREE_VIEW_HEADER_HEIGHT + (GTK_TREE_VIEW(event_viewer_data->tree_v)); + requisition->height = h; + +} + +gboolean show_event_detail(void * hook_data, void * call_data) +{ + EventViewerData *event_viewer_data = (EventViewerData*) hook_data; + LttvTracesetContext * tsc = get_traceset_context(event_viewer_data->mw); + + if(event_viewer_data->shown == FALSE){ + event_viewer_data->shown = TRUE; + update_raw_data_array(event_viewer_data, + event_viewer_data->raw_trace_data_queue_tmp->length); + + get_test_data(event_viewer_data->vadjust_c->value, + event_viewer_data->num_visible_events, + event_viewer_data); + + remove_context_hooks(event_viewer_data,tsc); + } + + return FALSE; +} + +void insert_data_into_model(EventViewerData *event_viewer_data, int start, int end) +{ + int i; + guint64 real_data; + RawTraceData * raw_data; + GList * first; + GtkTreeIter iter; + + first = event_viewer_data->raw_trace_data_queue->head; + for(i=start; i=event_viewer_data->number_of_events) break; + raw_data = (RawTraceData*)g_list_nth_data(first, i); + + // Add a new row to the model + real_data = raw_data->time.tv_sec; + real_data *= NANOSECONDS_PER_SECOND; + real_data += raw_data->time.tv_nsec; + gtk_list_store_append (event_viewer_data->store_m, &iter); + gtk_list_store_set (event_viewer_data->store_m, &iter, + CPUID_COLUMN, raw_data->cpu_id, + EVENT_COLUMN, raw_data->event_name, + TIME_COLUMN, real_data, + PID_COLUMN, raw_data->pid, + ENTRY_LEN_COLUMN, raw_data->entry_length, + EVENT_DESCR_COLUMN, raw_data->event_description, + -1); + } +} + +void get_test_data(double time_value, guint list_height, + EventViewerData *event_viewer_data) +{ + GtkTreeIter iter; + int i; + GtkTreeModel *model = GTK_TREE_MODEL(event_viewer_data->store_m); + GtkTreePath *tree_path; + RawTraceData * raw_data; + ScrollDirection direction = SCROLL_NONE; + GList * first; + int event_number; + double value = event_viewer_data->previous_value - time_value; + LttTime start, end, time; + LttEvent * ev; + unsigned backward_num, minNum, maxNum; + LttTracefile * tf; + unsigned block_num, event_num; + unsigned size = 1, count = 0; + gboolean need_backward_again, backward; + GdkWindow * win; + GdkCursor * new; + GtkWidget* widget = gtk_widget_get_parent(event_viewer_data->hbox_v); + + if(widget){ + new = gdk_cursor_new(GDK_X_CURSOR); + win = gtk_widget_get_parent_window(widget); + gdk_window_set_cursor(win, new); + gdk_cursor_unref(new); + gdk_window_stick(win); + gdk_window_unstick(win); + } + + + // if(event_number > event_viewer_data->last_event || + // event_number + list_height-1 < event_viewer_data->first_event || + // event_viewer_data->first_event == -1) + { + /* no event can be reused, clear and start from nothing */ + if(value == -1.0) direction = SCROLL_STEP_DOWN; + else if(value == 1.0 ) direction = SCROLL_STEP_UP; + else if(value == -2.0) direction = SCROLL_PAGE_DOWN; + else if(value == 2.0 ) direction = SCROLL_PAGE_UP; + else if(value == 0.0 ) direction = SCROLL_NONE; + else direction = SCROLL_JUMP; + + switch(direction){ + case SCROLL_STEP_UP: + case SCROLL_PAGE_UP: + if(direction == SCROLL_PAGE_UP){ + backward = list_height>event_viewer_data->start_event_index ? TRUE : FALSE; + }else{ + backward = event_viewer_data->start_event_index == 0 ? TRUE : FALSE; + } + if(backward){ + event_viewer_data->append = FALSE; + do{ + if(direction == SCROLL_PAGE_UP){ + minNum = list_height - event_viewer_data->start_event_index ; + }else{ + minNum = 1; + } + + first = event_viewer_data->raw_trace_data_queue->head; + if(!first)break; + raw_data = (RawTraceData*)g_list_nth_data(first,0); + end = raw_data->time; + end.tv_nsec--; + ltt_event_position_get(raw_data->ep, &block_num, &event_num, &tf); + if(size !=0){ + if(event_num > minNum){ + backward_num = event_num > RESERVE_SMALL_SIZE + ? event_num - RESERVE_SMALL_SIZE : 1; + ltt_event_position_set(raw_data->ep, block_num, backward_num); + ltt_tracefile_seek_position(tf, raw_data->ep); + ev = ltt_tracefile_read(tf); + start = ltt_event_time(ev); + maxNum = RESERVE_SMALL_SIZE_CUBE; + }else{ + if(block_num > 1){ + ltt_event_position_set(raw_data->ep, block_num-1, 1); + ltt_tracefile_seek_position(tf, raw_data->ep); + ev = ltt_tracefile_read(tf); + start = ltt_event_time(ev); + }else{ + start.tv_sec = 0; + start.tv_nsec = 0; + } + maxNum = RESERVE_SMALL_SIZE_CUBE; + } + }else{ + if(block_num > count){ + ltt_event_position_set(raw_data->ep, block_num-count, 1); + ltt_tracefile_seek_position(tf, raw_data->ep); + ev = ltt_tracefile_read(tf); + start = ltt_event_time(ev); + }else{ + start.tv_sec = 0; + start.tv_nsec = 0; + } + maxNum = RESERVE_SMALL_SIZE_CUBE; + } + + event_viewer_data->current_event_index = event_viewer_data->start_event_index; + get_events(event_viewer_data, start, end, maxNum, &size); + event_viewer_data->start_event_index = event_viewer_data->current_event_index; + + if(size < minNum && (start.tv_sec !=0 || start.tv_nsec !=0)) + need_backward_again = TRUE; + else need_backward_again = FALSE; + if(size == 0){ + count++; + }else{ + count = 0; + } + }while(need_backward_again); + } + if(direction == SCROLL_STEP_UP) + event_number = event_viewer_data->start_event_index - 1; + else + event_number = event_viewer_data->start_event_index - list_height; + break; + case SCROLL_STEP_DOWN: + if(event_viewer_data->end_event_index == event_viewer_data->number_of_events - 1){ + event_viewer_data->append = TRUE; + first = event_viewer_data->raw_trace_data_queue->head; + if(!first)break; + raw_data = (RawTraceData*)g_list_nth_data(first,event_viewer_data->number_of_events - 1); + start = raw_data->time; + start.tv_nsec++; + end.tv_sec = G_MAXULONG; + end.tv_nsec = G_MAXULONG; + get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE, &size); + if(size == 0){ + get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_SQUARE,&size); + if(size == 0) + get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_CUBE,&size); + } + if(size==0) event_number = event_viewer_data->start_event_index; + else event_number = event_viewer_data->number_of_events - size - list_height + 1; + }else event_number = event_viewer_data->start_event_index + 1; + break; + case SCROLL_PAGE_DOWN: + i = event_viewer_data->number_of_events - 1 - list_height; + if((gint)(event_viewer_data->end_event_index) >= i){ + int remain_events = event_viewer_data->number_of_events - 1 + - event_viewer_data->end_event_index; + event_viewer_data->append = TRUE; + first = event_viewer_data->raw_trace_data_queue->head; + if(!first)break; + raw_data = (RawTraceData*)g_list_nth_data(first,event_viewer_data->number_of_events - 1); + start = raw_data->time; + start.tv_nsec++; + end.tv_sec = G_MAXULONG; + end.tv_nsec = G_MAXULONG; + get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE,&size); + if(size == 0){ + get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_SQUARE,&size); + if(size == 0) + get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_CUBE,&size); + } + remain_events += size; + if(list_height <= remain_events) + event_number = event_viewer_data->number_of_events - remain_events - 1; + else + event_number = event_viewer_data->number_of_events - 1 - list_height; + }else event_number = event_viewer_data->start_event_index + list_height - 1; + break; + case SCROLL_JUMP: + event_viewer_data->append = TRUE; + remove_all_items_from_queue(event_viewer_data->raw_trace_data_queue); + end.tv_sec = G_MAXULONG; + end.tv_nsec = G_MAXULONG; + time = ltt_time_from_double(time_value / NANOSECONDS_PER_SECOND); + start = ltt_time_add(event_viewer_data->time_span.startTime, time); + event_viewer_data->previous_value = time_value; + get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE,&size); + if(size < list_height && size > 0){ + event_viewer_data->append = FALSE; + first = event_viewer_data->raw_trace_data_queue->head; + if(!first)break; + raw_data = (RawTraceData*)g_list_nth_data(first,0); + end = raw_data->time; + end.tv_nsec--; + ltt_event_position_get(raw_data->ep, &block_num, &event_num, &tf); + + if(event_num > list_height - size){ + backward_num = event_num > RESERVE_SMALL_SIZE + ? event_num - RESERVE_SMALL_SIZE : 1; + ltt_event_position_set(raw_data->ep, block_num, backward_num); + ltt_tracefile_seek_position(tf, raw_data->ep); + ev = ltt_tracefile_read(tf); + start = ltt_event_time(ev); + maxNum = RESERVE_SMALL_SIZE_CUBE; + event_viewer_data->current_event_index = 0; + get_events(event_viewer_data, start, end, maxNum, &size); + event_viewer_data->start_event_index = event_viewer_data->current_event_index; + } + event_number = event_viewer_data->raw_trace_data_queue->length - list_height; + }else if(size == 0){ + get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_SQUARE,&size); + if(size == 0) + get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_CUBE,&size); + event_number = 0; + }else{ + event_number = 0; + } + break; + case SCROLL_NONE: + event_number = event_viewer_data->current_event_index; + break; + default: + break; + } + + if(event_number < 0) event_number = 0; + + //update the value of the scroll bar + if(direction != SCROLL_NONE && direction != SCROLL_JUMP){ + first = event_viewer_data->raw_trace_data_queue->head; + if(first){ + raw_data = (RawTraceData*)g_list_nth_data(first,event_number); + if(!raw_data) raw_data = (RawTraceData*)g_list_nth_data(first,0); + time = ltt_time_sub(raw_data->time, event_viewer_data->time_span.startTime); + event_viewer_data->vadjust_c->value = ltt_time_to_double(time) * NANOSECONDS_PER_SECOND; + g_signal_stop_emission_by_name(G_OBJECT(event_viewer_data->vadjust_c), "value-changed"); + event_viewer_data->previous_value = event_viewer_data->vadjust_c->value; + } + } + + + event_viewer_data->start_event_index = event_number; + event_viewer_data->end_event_index = event_number + list_height - 1; + if(event_viewer_data->end_event_index > event_viewer_data->number_of_events - 1){ + event_viewer_data->end_event_index = event_viewer_data->number_of_events - 1; + } + + first = event_viewer_data->raw_trace_data_queue->head; + gtk_list_store_clear(event_viewer_data->store_m); + if(!first){ + // event_viewer_data->previous_value = 0; + // event_viewer_data->vadjust_c->value = 0.0; + // gtk_widget_hide(event_viewer_data->vscroll_vc); + goto LAST; + }else gtk_widget_show(event_viewer_data->vscroll_vc); + + insert_data_into_model(event_viewer_data,event_number, event_number+list_height); + } +#ifdef DEBUG //do not use this, it's slower and broken + // } else { + /* Some events will be reused */ + if(event_number < event_viewer_data->first_event) + { + /* scrolling up, prepend events */ + tree_path = gtk_tree_path_new_from_indices + (event_number+list_height-1 - + event_viewer_data->first_event + 1, + -1); + for(i=0; ilast_event-(event_number+list_height-1); + i++) + { + /* Remove the last events from the list */ + if(gtk_tree_model_get_iter(model, &iter, tree_path)) + gtk_list_store_remove(event_viewer_data->store_m, &iter); + } + + for(i=event_viewer_data->first_event-1; i>=event_number; i--) + { + if(i>=event_viewer_data->number_of_events) break; + /* Prepend new events */ + gtk_list_store_prepend (event_viewer_data->store_m, &iter); + gtk_list_store_set (event_viewer_data->store_m, &iter, + CPUID_COLUMN, 0, + EVENT_COLUMN, "event irq", + TIME_COLUMN, i, + PID_COLUMN, 100, + ENTRY_LEN_COLUMN, 17, + EVENT_DESCR_COLUMN, "Detailed information", + -1); + } + } else { + /* Scrolling down, append events */ + for(i=event_viewer_data->first_event; istore_m, &iter); + } + for(i=event_viewer_data->last_event+1; i=event_viewer_data->number_of_events) break; + /* Append new events */ + gtk_list_store_append (event_viewer_data->store_m, &iter); + gtk_list_store_set (event_viewer_data->store_m, &iter, + CPUID_COLUMN, 0, + EVENT_COLUMN, "event irq", + TIME_COLUMN, i, + PID_COLUMN, 100, + ENTRY_LEN_COLUMN, 17, + EVENT_DESCR_COLUMN, "Detailed information", + -1); + } + + } + //} +#endif //DEBUG + event_viewer_data->first_event = event_viewer_data->start_event_index ; + event_viewer_data->last_event = event_viewer_data->end_event_index ; + + LAST: + if(widget) + gdk_window_set_cursor(win, NULL); + +} + + +void add_test_data(EventViewerData *event_viewer_data) +{ + GtkTreeIter iter; + int i; + + for(i=0; i<10; i++) + { + /* Add a new row to the model */ + gtk_list_store_append (event_viewer_data->store_m, &iter); + gtk_list_store_set (event_viewer_data->store_m, &iter, + CPUID_COLUMN, 0, + EVENT_COLUMN, "event irq", + TIME_COLUMN, i, + PID_COLUMN, 100, + ENTRY_LEN_COLUMN, 17, + EVENT_DESCR_COLUMN, "Detailed information", + -1); + } + +} + +void +gui_events_free(EventViewerData *event_viewer_data) +{ + if(event_viewer_data){ + lttv_hooks_remove(event_viewer_data->before_event_hooks,parse_event); + lttv_hooks_destroy(event_viewer_data->before_event_hooks); + + remove_all_items_from_queue (event_viewer_data->raw_trace_data_queue); + g_queue_free(event_viewer_data->raw_trace_data_queue); + g_queue_free(event_viewer_data->raw_trace_data_queue_tmp); + + unreg_update_time_window(update_time_window,event_viewer_data, event_viewer_data->mw); + unreg_update_current_time(update_current_time,event_viewer_data, event_viewer_data->mw); + unreg_show_viewer(show_event_detail,event_viewer_data, event_viewer_data->mw); + unreg_update_traceset(traceset_changed,event_viewer_data, event_viewer_data->mw); + + g_event_viewer_data_list = g_slist_remove(g_event_viewer_data_list, event_viewer_data); + g_free(event_viewer_data); + } +} + +void +gui_events_destructor(EventViewerData *event_viewer_data) +{ + guint index; + + /* May already been done by GTK window closing */ + if(GTK_IS_WIDGET(event_viewer_data->hbox_v)){ + gtk_widget_destroy(event_viewer_data->hbox_v); + g_free(event_viewer_data->filter_key); + event_viewer_data = NULL; + } + + /* Destroy the Tree View */ + //gtk_widget_destroy(event_viewer_data->tree_v); + + /* Clear raw event list */ + //gtk_list_store_clear(event_viewer_data->store_m); + //gtk_widget_destroy(GTK_WIDGET(event_viewer_data->store_m)); + + //gui_events_free(event_viewer_data); +} + +//FIXME : call hGuiEvents_Destructor for corresponding data upon widget destroy + +static void +tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data) +{ + EventViewerData *event_viewer_data = (EventViewerData*)data; + GtkTreeIter iter; + GtkTreeModel *model = GTK_TREE_MODEL(event_viewer_data->store_m); + gchar *event; + + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + { + gtk_tree_model_get (model, &iter, EVENT_COLUMN, &event, -1); + + g_free (event); + } +} + + +int event_selected_hook(void *hook_data, void *call_data) +{ + EventViewerData *event_viewer_data = (EventViewerData*) hook_data; + guint *event_number = (guint*) call_data; + + event_viewer_data->currently_selected_event = *event_number; + event_viewer_data->selected_event = TRUE ; + + tree_v_set_cursor(event_viewer_data); + +} + +/* If every module uses the filter, maybe these two + * (add/remove_context_hooks functions) should be put in common place + */ +void add_context_hooks(EventViewerData * event_viewer_data, + LttvTracesetContext * tsc) +{ + gint i, j, k, m,n, nbi, id; + gint nb_tracefile, nb_control, nb_per_cpu, nb_facility, nb_event; + LttTrace *trace; + LttvTraceContext *tc; + LttvTracefileContext *tfc; + LttvTracesetSelector * ts_s; + LttvTraceSelector * t_s; + LttvTracefileSelector * tf_s; + gboolean selected; + LttFacility * fac; + LttEventType * et; + LttvEventtypeSelector * eventtype; + + ts_s = (LttvTracesetSelector*)g_object_get_data(G_OBJECT(event_viewer_data->hbox_v), + event_viewer_data->filter_key); + + //if there are hooks for traceset, add them here + + nbi = lttv_traceset_number(tsc->ts); + for(i = 0 ; i < nbi ; i++) { + t_s = lttv_traceset_selector_trace_get(ts_s,i); + selected = lttv_trace_selector_get_selected(t_s); + if(!selected) continue; + tc = tsc->traces[i]; + trace = tc->t; + //if there are hooks for trace, add them here + + nb_control = ltt_trace_control_tracefile_number(trace); + nb_per_cpu = ltt_trace_per_cpu_tracefile_number(trace); + nb_tracefile = nb_control + nb_per_cpu; + + for(j = 0 ; j < nb_tracefile ; j++) { + tf_s = lttv_trace_selector_tracefile_get(t_s,j); + selected = lttv_tracefile_selector_get_selected(tf_s); + if(!selected) continue; + + if(j < nb_control) + tfc = tc->control_tracefiles[j]; + else + tfc = tc->per_cpu_tracefiles[j - nb_control]; + + //if there are hooks for tracefile, add them here + // lttv_tracefile_context_add_hooks(tfc, NULL,NULL,NULL,NULL, + // event_viewer_data->before_event_hooks,NULL); + + nb_facility = ltt_trace_facility_number(trace); + n = 0; + for(k=0;kbefore_event_hooks, + NULL); + } + n++; + } + } + + } + } + + //add hooks for process_traceset + // context_add_hooks_api(event_viewer_data->mw, NULL, NULL, NULL, NULL, NULL, NULL, + // NULL, NULL, NULL,event_viewer_data->before_event_hooks,NULL); +} + + +void remove_context_hooks(EventViewerData * event_viewer_data, + LttvTracesetContext * tsc) +{ + gint i, j, k, m, nbi, n, id; + gint nb_tracefile, nb_control, nb_per_cpu, nb_facility, nb_event; + LttTrace *trace; + LttvTraceContext *tc; + LttvTracefileContext *tfc; + LttvTracesetSelector * ts_s; + LttvTraceSelector * t_s; + LttvTracefileSelector * tf_s; + gboolean selected; + LttFacility * fac; + LttEventType * et; + LttvEventtypeSelector * eventtype; + + ts_s = (LttvTracesetSelector*)g_object_get_data(G_OBJECT(event_viewer_data->hbox_v), + event_viewer_data->filter_key); + + //if there are hooks for traceset, remove them here + + nbi = lttv_traceset_number(tsc->ts); + for(i = 0 ; i < nbi ; i++) { + t_s = lttv_traceset_selector_trace_get(ts_s,i); + selected = lttv_trace_selector_get_selected(t_s); + if(!selected) continue; + tc = tsc->traces[i]; + trace = tc->t; + //if there are hooks for trace, remove them here + + nb_control = ltt_trace_control_tracefile_number(trace); + nb_per_cpu = ltt_trace_per_cpu_tracefile_number(trace); + nb_tracefile = nb_control + nb_per_cpu; + + for(j = 0 ; j < nb_tracefile ; j++) { + tf_s = lttv_trace_selector_tracefile_get(t_s,j); + selected = lttv_tracefile_selector_get_selected(tf_s); + if(!selected) continue; + + if(j < nb_control) + tfc = tc->control_tracefiles[j]; + else + tfc = tc->per_cpu_tracefiles[j - nb_control]; + + //if there are hooks for tracefile, remove them here + // lttv_tracefile_context_remove_hooks(tfc, NULL,NULL,NULL,NULL, + // event_viewer_data->before_event_hooks,NULL); + + nb_facility = ltt_trace_facility_number(trace); + n = 0; + for(k=0;kmw, NULL, NULL, NULL, NULL, NULL, NULL, + // NULL, NULL, NULL,event_viewer_data->before_event_hooks,NULL); +} + + +gboolean update_time_window(void * hook_data, void * call_data) +{ + EventViewerData *event_viewer_data = (EventViewerData*) hook_data; + LttvTracesetContext * tsc = get_traceset_context(event_viewer_data->mw); + + if(event_viewer_data->shown == FALSE){ + event_viewer_data->time_window = *(TimeWindow*)call_data; + + add_context_hooks(event_viewer_data, tsc); + } + + return FALSE; +} + +gboolean update_current_time(void * hook_data, void * call_data) +{ + EventViewerData *event_viewer_data = (EventViewerData*) hook_data; + event_viewer_data->current_time = *(LttTime*)call_data; + guint64 nsec = event_viewer_data->current_time.tv_sec * NANOSECONDS_PER_SECOND + + event_viewer_data->current_time.tv_nsec; + GtkTreeIter iter; + guint64 time; + int count = -1; + GtkTreeModel* model = (GtkTreeModel*)event_viewer_data->store_m; + GList * list; + RawTraceData * data, *data1; + GtkTreePath* path; + char str_path[64]; + int i, j; + LttTime t; + + if(event_viewer_data->current_time_updated ){ + event_viewer_data->current_time_updated = FALSE; + return FALSE; + } + + //check if the event is shown in the current viewer + if(gtk_tree_model_get_iter_first(model, &iter)){ + while(1){ + gtk_tree_model_get(model, &iter, TIME_COLUMN, &time, -1); + if(time < nsec){ + if(!gtk_tree_model_iter_next(model, &iter)){ + count = -1; + break; + } + count++; + }else{ + break; + } + } + // event_selected_hook(event_viewer_data, &count); + } + + //the event is not shown in the current viewer + if(count == -1){ + count = 0; + //check if the event is in the buffer + list = event_viewer_data->raw_trace_data_queue->head; + data = (RawTraceData*)g_list_nth_data(list,0); + data1 = (RawTraceData*)g_list_nth_data(list,event_viewer_data->raw_trace_data_queue->length-1); + + //the event is in the buffer + if(ltt_time_compare(data->time, event_viewer_data->current_time)<=0 && + ltt_time_compare(data1->time, event_viewer_data->current_time)>=0){ + for(i=0;iraw_trace_data_queue->length;i++){ + data = (RawTraceData*)g_list_nth_data(list,i); + if(ltt_time_compare(data->time, event_viewer_data->current_time) < 0){ + count++; + continue; + } + break; + } + if(event_viewer_data->raw_trace_data_queue->length-count < event_viewer_data->num_visible_events){ + j = event_viewer_data->raw_trace_data_queue->length - event_viewer_data->num_visible_events; + count -= j; + data = (RawTraceData*)g_list_nth_data(list,j); + }else{ + j = count; + count = 0; + } + t = ltt_time_sub(data->time, event_viewer_data->time_span.startTime); + event_viewer_data->vadjust_c->value = ltt_time_to_double(t) * NANOSECONDS_PER_SECOND; + g_signal_stop_emission_by_name(G_OBJECT(event_viewer_data->vadjust_c), "value-changed"); + event_viewer_data->previous_value = event_viewer_data->vadjust_c->value; + insert_data_into_model(event_viewer_data,j, j+event_viewer_data->num_visible_events); + }else{//the event is not in the buffer + LttTime start = ltt_time_sub(event_viewer_data->current_time, event_viewer_data->time_span.startTime); + double position = ltt_time_to_double(start) * NANOSECONDS_PER_SECOND; + gtk_adjustment_set_value(event_viewer_data->vadjust_c, position); + } + } + + sprintf(str_path,"%d\0",count); + path = gtk_tree_path_new_from_string (str_path); + gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE); + g_signal_stop_emission_by_name(G_OBJECT(event_viewer_data->tree_v), "cursor-changed"); + gtk_tree_path_free(path); + + return FALSE; +} + +gboolean traceset_changed(void * hook_data, void * call_data) +{ + EventViewerData *event_viewer_data = (EventViewerData*) hook_data; + LttTime start; + + remove_all_items_from_queue(event_viewer_data->raw_trace_data_queue); + gtk_list_store_clear(event_viewer_data->store_m); + event_viewer_data->shown = FALSE; + event_viewer_data->append = TRUE; + + get_traceset_time_span(event_viewer_data->mw, &event_viewer_data->time_span); + start = ltt_time_sub(event_viewer_data->time_span.endTime, event_viewer_data->time_span.startTime); + event_viewer_data->vadjust_c->upper = ltt_time_to_double(start) * NANOSECONDS_PER_SECOND; + // event_viewer_data->vadjust_c->value = 0; + + return FALSE; +} + + +void tree_v_grab_focus(GtkWidget *widget, gpointer data){ + EventViewerData *event_viewer_data = (EventViewerData *)data; + MainWindow * mw = event_viewer_data->mw; + set_focused_pane(mw, gtk_widget_get_parent(event_viewer_data->hbox_v)); +} + +void update_raw_data_array(EventViewerData* event_viewer_data, unsigned size) +{ + RawTraceData * data; + if(size > 0){ + int pid, tmpPid, i,j,len; + GList * list, *tmpList; + GArray * pid_array, * tmp_pid_array; + + pid_array = g_array_sized_new(FALSE, TRUE, sizeof(int), 10); + tmp_pid_array = g_array_sized_new(FALSE, TRUE, sizeof(int), 10); + + //if the queue is full, remove some data, keep the size of the queue constant + while(event_viewer_data->raw_trace_data_queue->length + size > RESERVE_BIG_SIZE){ + remove_item_from_queue(event_viewer_data->raw_trace_data_queue, + event_viewer_data->append); + } + + //update pid if it is not known + if(event_viewer_data->raw_trace_data_queue->length > 0){ + list = event_viewer_data->raw_trace_data_queue->head; + tmpList = event_viewer_data->raw_trace_data_queue_tmp->head; + if(event_viewer_data->append){ + for(i= event_viewer_data->raw_trace_data_queue->length-1;i>=0;i--){ + data = (RawTraceData*)g_list_nth_data(list,i); + len = data->pid==0 ? -2 : data->pid; + if(data->cpu_id+1 > pid_array->len){ + pid_array = g_array_set_size(pid_array,data->cpu_id+1); + pid_array = g_array_insert_val(pid_array,data->cpu_id,len); + pid_array = g_array_remove_index(pid_array,data->cpu_id+1); + }else if(data->cpu_id+1 < pid_array->len){ + pid = g_array_index(pid_array,int,data->cpu_id); + if(pid == 0){ + pid_array = g_array_insert_val(pid_array,data->cpu_id,len); + pid_array = g_array_remove_index(pid_array,data->cpu_id+1); + } + } + } + + for(i=0;iraw_trace_data_queue_tmp->length;i++){ + data = (RawTraceData*)g_list_nth_data(tmpList,i); + len = data->pid==0 ? -2 : data->pid; + if(data->cpu_id+1 > tmp_pid_array->len){ + tmp_pid_array = g_array_set_size(tmp_pid_array,data->cpu_id+1); + tmp_pid_array = g_array_insert_val(tmp_pid_array,data->cpu_id,len); + tmp_pid_array = g_array_remove_index(tmp_pid_array,data->cpu_id+1); + }else if(data->cpu_id+1 < tmp_pid_array->len){ + pid = g_array_index(tmp_pid_array,int,data->cpu_id); + if(pid == 0){ + tmp_pid_array = g_array_insert_val(tmp_pid_array,data->cpu_id,len); + tmp_pid_array = g_array_remove_index(tmp_pid_array,data->cpu_id+1); + } + } + } + }else{ + for(i=0;iraw_trace_data_queue->length;i++){ + data = (RawTraceData*)g_list_nth_data(list,i); + len = data->pid==0 ? -2 : data->pid; + if(data->cpu_id+1 > pid_array->len){ + pid_array = g_array_set_size(pid_array,data->cpu_id+1); + pid_array = g_array_insert_val(pid_array,data->cpu_id,len); + pid_array = g_array_remove_index(pid_array,data->cpu_id+1); + }else if(data->cpu_id+1 < pid_array->len){ + pid = g_array_index(pid_array,int,data->cpu_id); + if(pid == 0){ + pid_array = g_array_insert_val(pid_array,data->cpu_id,len); + pid_array = g_array_remove_index(pid_array,data->cpu_id+1); + } + } + } + + for(i=event_viewer_data->raw_trace_data_queue_tmp->length-1;i>=0;i--){ + data = (RawTraceData*)g_list_nth_data(tmpList,i); + len = data->pid==0 ? -2 : data->pid; + if(data->cpu_id+1 > tmp_pid_array->len){ + tmp_pid_array = g_array_set_size(tmp_pid_array,data->cpu_id+1); + tmp_pid_array = g_array_insert_val(tmp_pid_array,data->cpu_id,len); + tmp_pid_array = g_array_remove_index(tmp_pid_array,data->cpu_id+1); + }else if(data->cpu_id+1 < tmp_pid_array->len){ + pid = g_array_index(tmp_pid_array,int,data->cpu_id); + if(pid == 0){ + tmp_pid_array = g_array_insert_val(tmp_pid_array,data->cpu_id,len); + tmp_pid_array = g_array_remove_index(tmp_pid_array,data->cpu_id+1); + } + } + } + } + + len = pid_array->len > tmp_pid_array->len ? tmp_pid_array->len : pid_array->len; + for(j=0;jraw_trace_data_queue->length;i++){ + data = (RawTraceData*)g_list_nth_data(list,i); + if(data->pid == -1 && data->cpu_id == j) data->pid = tmpPid; + } + }else if(pid != -1 && tmpPid == -1){ + for(i=0;iraw_trace_data_queue_tmp->length;i++){ + data = (RawTraceData*)g_list_nth_data(tmpList,i); + if(data->pid == -1 && data->cpu_id == j) data->pid = pid; + } + } + } + } + + g_array_free(pid_array,TRUE); + g_array_free(tmp_pid_array, TRUE); + + //add data from tmp queue into the queue + event_viewer_data->number_of_events = event_viewer_data->raw_trace_data_queue->length + + event_viewer_data->raw_trace_data_queue_tmp->length; + if(event_viewer_data->append){ + if(event_viewer_data->raw_trace_data_queue->length > 0) + event_viewer_data->current_event_index = event_viewer_data->raw_trace_data_queue->length - 1; + else event_viewer_data->current_event_index = 0; + while((data = g_queue_pop_head(event_viewer_data->raw_trace_data_queue_tmp)) != NULL){ + g_queue_push_tail(event_viewer_data->raw_trace_data_queue, data); + } + }else{ + event_viewer_data->current_event_index += event_viewer_data->raw_trace_data_queue_tmp->length; + while((data = g_queue_pop_tail(event_viewer_data->raw_trace_data_queue_tmp)) != NULL){ + g_queue_push_head(event_viewer_data->raw_trace_data_queue, data); + } + } + } +} + +void get_events(EventViewerData* event_viewer_data, LttTime start, + LttTime end,unsigned max_num_events, unsigned * real_num_events) +{ + int size; + LttvTracesetContext * tsc = get_traceset_context(event_viewer_data->mw); + + // context_add_hooks_api(event_viewer_data->mw, NULL, NULL, NULL, NULL, NULL, NULL, + // NULL, NULL, NULL,event_viewer_data->before_event_hooks,NULL); + add_context_hooks(event_viewer_data,tsc); + + process_traceset_api(event_viewer_data->mw, start, end, max_num_events); + + remove_context_hooks(event_viewer_data,tsc); + // context_remove_hooks_api(event_viewer_data->mw, NULL, NULL, NULL, NULL, NULL, NULL, + // NULL, NULL, NULL,event_viewer_data->before_event_hooks,NULL); + + size = event_viewer_data->raw_trace_data_queue_tmp->length; + *real_num_events = size; + + update_raw_data_array(event_viewer_data,size); +} + +static void get_event_detail(LttEvent *e, LttField *f, GString * s) +{ + LttType *type; + LttField *element; + char *name; + int nb, i; + + type = ltt_field_type(f); + switch(ltt_type_class(type)) { + case LTT_INT: + g_string_append_printf(s, " %ld", ltt_event_get_long_int(e,f)); + break; + + case LTT_UINT: + g_string_append_printf(s, " %lu", ltt_event_get_long_unsigned(e,f)); + break; + + case LTT_FLOAT: + g_string_append_printf(s, " %g", ltt_event_get_double(e,f)); + break; + + case LTT_STRING: + g_string_append_printf(s, " \"%s\"", ltt_event_get_string(e,f)); + break; + + case LTT_ENUM: + g_string_append_printf(s, " %s", ltt_enum_string_get(type, + ltt_event_get_unsigned(e,f)-1)); + break; + + case LTT_ARRAY: + case LTT_SEQUENCE: + g_string_append_printf(s, " {"); + nb = ltt_event_field_element_number(e,f); + element = ltt_field_element(f); + for(i = 0 ; i < nb ; i++) { + ltt_event_field_element_select(e,f,i); + get_event_detail(e, element, s); + } + g_string_append_printf(s, " }"); + break; + + case LTT_STRUCT: + g_string_append_printf(s, " {"); + nb = ltt_type_member_number(type); + for(i = 0 ; i < nb ; i++) { + element = ltt_field_member(f,i); + ltt_type_member_type(type, i, &name); + g_string_append_printf(s, " %s = ", name); + get_event_detail(e, element, s); + } + g_string_append_printf(s, " }"); + break; + } + +} + +static void get_pid(unsigned * in, unsigned * out, char * s) +{ + char * str; + str = strstr(s, "out ="); + if (str){ + str = str + 5; + sscanf(str,"%d", out); + }else{ + g_warning("Can not find out pid\n"); + } + + str = strstr(s,"in ="); + if (str){ + str = str + 4; + sscanf(str,"%d", in); + }else{ + g_warning("Can not find in pid\n"); + } +} + +gboolean parse_event(void *hook_data, void *call_data) +{ + EventViewerData *event_viewer_data = (EventViewerData *)hook_data; + LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; + LttvTracefileState *tfs = (LttvTracefileState *)call_data; + + RawTraceData * tmp_raw_trace_data,*prev_raw_trace_data = NULL, *data=NULL; + LttEvent *e; + LttTime time; + LttField * field; + unsigned in=0, out=0; + int i; + GString * detail_event = g_string_new(""); + GList * list; + + e = tfc->e; + field = ltt_event_field(e); + time = ltt_event_time(e); + + tmp_raw_trace_data = g_new(RawTraceData,1); + tmp_raw_trace_data->cpu_id = ltt_event_cpu_id(e); + tmp_raw_trace_data->event_name = g_strdup(ltt_eventtype_name(ltt_event_eventtype(e))); + tmp_raw_trace_data->time = time; + tmp_raw_trace_data->ep = ltt_event_position_new(); + + if(event_viewer_data->raw_trace_data_queue_tmp->length){ + list = event_viewer_data->raw_trace_data_queue_tmp->head; + for(i=event_viewer_data->raw_trace_data_queue_tmp->length-1;i>=0;i--){ + data = (RawTraceData *)g_list_nth_data(list,i); + if(data->cpu_id == tmp_raw_trace_data->cpu_id){ + prev_raw_trace_data = data; + break; + } + } + } + + if(prev_raw_trace_data) tmp_raw_trace_data->pid = prev_raw_trace_data->pid; + else tmp_raw_trace_data->pid = -1; + + tmp_raw_trace_data->entry_length = field == NULL ? 0 : ltt_field_size(field); + if(field) get_event_detail(e, field, detail_event); + tmp_raw_trace_data->event_description = g_strdup(detail_event->str); + + if(strcmp(tmp_raw_trace_data->event_name, "schedchange") == 0){ + get_pid(&in, &out, detail_event->str); + } + + + if(in != 0 || out != 0){ + tmp_raw_trace_data->pid = in; + if(prev_raw_trace_data && prev_raw_trace_data->pid == -1){ + list = event_viewer_data->raw_trace_data_queue_tmp->head; + for(i=0;iraw_trace_data_queue_tmp->length;i++){ + data = (RawTraceData *)g_list_nth_data(list,i); + if(data->cpu_id == tmp_raw_trace_data->cpu_id){ + data->pid = out; + } + } + } + } + + ltt_event_position(e, tmp_raw_trace_data->ep); + + if(event_viewer_data->raw_trace_data_queue_tmp->length >= RESERVE_SMALL_SIZE){ + if(event_viewer_data->append){ + list = g_list_last(event_viewer_data->raw_trace_data_queue_tmp->head); + data = (RawTraceData *)(list->data); + if(data->time.tv_sec == time.tv_sec && + data->time.tv_nsec == time.tv_nsec){ + g_queue_push_tail(event_viewer_data->raw_trace_data_queue_tmp,tmp_raw_trace_data); + }else{ + g_free(tmp_raw_trace_data); + } + }else{ + remove_item_from_queue(event_viewer_data->raw_trace_data_queue_tmp,TRUE); + g_queue_push_tail(event_viewer_data->raw_trace_data_queue_tmp,tmp_raw_trace_data); + } + }else{ + g_queue_push_tail (event_viewer_data->raw_trace_data_queue_tmp,tmp_raw_trace_data); + } + + g_string_free(detail_event, TRUE); + + return FALSE; +} + +void remove_item_from_queue(GQueue * q, gboolean fromHead) +{ + RawTraceData *data1, *data2 = NULL; + GList * list; + + if(fromHead){ + data1 = (RawTraceData *)g_queue_pop_head(q); + list = g_list_first(q->head); + if(list) + data2 = (RawTraceData *)(list->data); + }else{ + data1 = (RawTraceData *)g_queue_pop_tail(q); + list = g_list_last(q->head); + if(list) + data2 = (RawTraceData *)(list->data); + } + + if(data2){ + if(data1->time.tv_sec == data2->time.tv_sec && + data1->time.tv_nsec == data2->time.tv_nsec){ + remove_item_from_queue(q, fromHead); + } + } + + g_free(data1); + + return; +} + +void remove_all_items_from_queue(GQueue *q) +{ + RawTraceData *data; + while((data = (RawTraceData *)g_queue_pop_head(q)) != NULL){ + g_free(data); + } +} + + diff --git a/ltt/branches/poly/lttv/modules/gui/Statistics/guiStatistic/Makefile.am b/ltt/branches/poly/lttv/modules/gui/Statistics/guiStatistic/Makefile.am new file mode 100644 index 00000000..0794479d --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/Statistics/guiStatistic/Makefile.am @@ -0,0 +1,16 @@ +# +# 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/API -lmainWinApi + +libdir = ${lttvplugindir} + +lib_LTLIBRARIES = libguiStatistic.la +libguiStatistic_la_LDFLAGS = -module +libguiStatistic_la_SOURCES = guiStatistic.c diff --git a/ltt/branches/poly/lttv/modules/gui/Statistics/guiStatistic/guiStatistic.c b/ltt/branches/poly/lttv/modules/gui/Statistics/guiStatistic/guiStatistic.c new file mode 100644 index 00000000..aef524e5 --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/Statistics/guiStatistic/guiStatistic.c @@ -0,0 +1,687 @@ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "../icons/hGuiStatisticInsert.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) + +#define PATH_LENGTH 256 + +static LttvModule *statistic_main_win_module; +static GPtrArray * statistic_traceset; + +/** Array containing instanced objects. Used when module is unloaded */ +static GSList *g_statistic_viewer_data_list = NULL ; + +typedef struct _StatisticViewerData StatisticViewerData; + +//! Statistic Viewer's constructor hook +GtkWidget *h_gui_statistic(MainWindow *parent_window, LttvTracesetSelector * s, char* key); +//! Statistic Viewer's constructor +StatisticViewerData *gui_statistic(MainWindow *parent_window,LttvTracesetSelector * s, char* key); +//! Statistic Viewer's destructor +void gui_statistic_destructor(StatisticViewerData *statistic_viewer_data); +void gui_statistic_free(StatisticViewerData *statistic_viewer_data); + +void grab_focus(GtkWidget *widget, gpointer data); +static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data); + +void statistic_destroy_hash_key(gpointer key); +void statistic_destroy_hash_data(gpointer data); + +void show_traceset_stats(StatisticViewerData * statistic_viewer_data); +void show_tree(StatisticViewerData * statistic_viewer_data, + LttvAttribute* stats, GtkTreeIter* parent); +void show_statistic(StatisticViewerData * statistic_viewer_data, + LttvAttribute* stats, GtkTextBuffer* buf); + + +/** hook functions for update time interval, current time ... */ +gboolean statistic_update_time_window(void * hook_data, void * call_data); +gboolean statistic_show_viewer(void * hook_data, void * call_data); +gboolean statistic_traceset_changed(void * hook_data, void * call_data); +void statistic_add_context_hooks(StatisticViewerData * statistic_viewer_data, + LttvTracesetContext * tsc); +void statistic_remove_context_hooks(StatisticViewerData * statistic_viewer_data, + LttvTracesetContext * tsc); + +gboolean statistic_insert_traceset_stats(void * stats); + +enum +{ + NAME_COLUMN, + N_COLUMNS +}; + +struct _StatisticViewerData{ + MainWindow * mw; + LttvTracesetStats * stats; + gboolean calculate_stats; + int size; + + TimeInterval time_span; + gboolean shown; //indicate if the statistic is shown or not + char * filter_key; + + GtkWidget * hpaned_v; + GtkTreeStore * store_m; + GtkWidget * tree_v; + + //scroll window containing Tree View + GtkWidget * scroll_win_tree; + + GtkWidget * text_v; + //scroll window containing Text View + GtkWidget * scroll_win_text; + + // Selection handler + GtkTreeSelection *select_c; + + //hash + GHashTable *statistic_hash; +}; + + +/** + * plugin's init function + * + * This function initializes the Statistic Viewer functionnality through the + * gtkTraceSet API. + */ +G_MODULE_EXPORT void init(LttvModule *self, int argc, char *argv[]) { + + statistic_main_win_module = lttv_module_require(self, "mainwin", argc, argv); + + if(statistic_main_win_module == NULL){ + g_critical("Can't load Statistic Viewer : missing mainwin\n"); + return; + } + + statistic_traceset = g_ptr_array_new (); + + /* Register the toolbar insert button */ + toolbar_item_reg(hGuiStatisticInsert_xpm, "Insert Statistic Viewer", h_gui_statistic); + + /* Register the menu item insert entry */ + menu_item_reg("/", "Insert Statistic Viewer", h_gui_statistic); + +} + +void statistic_destroy_walk(gpointer data, gpointer user_data) +{ + gui_statistic_destructor((StatisticViewerData*)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. + */ +G_MODULE_EXPORT void destroy() { + int i; + + if(g_statistic_viewer_data_list){ + g_slist_foreach(g_statistic_viewer_data_list, statistic_destroy_walk, NULL ); + g_slist_free(g_statistic_viewer_data_list); + } + g_ptr_array_free (statistic_traceset, TRUE); + + /* Unregister the toolbar insert button */ + toolbar_item_unreg(h_gui_statistic); + + /* Unregister the menu item insert entry */ + menu_item_unreg(h_gui_statistic); +} + + +void +gui_statistic_free(StatisticViewerData *statistic_viewer_data) +{ + if(statistic_viewer_data){ + unreg_update_time_window(statistic_update_time_window,statistic_viewer_data, statistic_viewer_data->mw); + unreg_show_viewer(statistic_show_viewer,statistic_viewer_data, statistic_viewer_data->mw); + unreg_update_traceset(statistic_traceset_changed,statistic_viewer_data, statistic_viewer_data->mw); + + g_hash_table_destroy(statistic_viewer_data->statistic_hash); + g_free(statistic_viewer_data->filter_key); + g_statistic_viewer_data_list = g_slist_remove(g_statistic_viewer_data_list, statistic_viewer_data); + g_free(statistic_viewer_data); + } +} + +void +gui_statistic_destructor(StatisticViewerData *statistic_viewer_data) +{ + /* May already been done by GTK window closing */ + if(GTK_IS_WIDGET(statistic_viewer_data->hpaned_v)){ + gtk_widget_destroy(statistic_viewer_data->hpaned_v); + statistic_viewer_data = NULL; + } + //gui_statistic_free(statistic_viewer_data); +} + + +/** + * Statistic Viewer's constructor hook + * + * This constructor is given as a parameter to the menuitem and toolbar button + * registration. It creates the list. + * @param parent_window A pointer to the parent window. + * @return The widget created. + */ +GtkWidget * +h_gui_statistic(MainWindow * parent_window, LttvTracesetSelector * s, char* key) +{ + StatisticViewerData* statistic_viewer_data = gui_statistic(parent_window, s, key) ; + + if(statistic_viewer_data) + return statistic_viewer_data->hpaned_v; + else return NULL; + +} + +gboolean statistic_insert_traceset_stats(void * stats) +{ + int i, len; + gpointer s; + + len = statistic_traceset->len; + for(i=0;imw = parent_window; + statistic_viewer_data->stats = get_traceset_stats_api(statistic_viewer_data->mw); + statistic_viewer_data->calculate_stats = statistic_insert_traceset_stats((void *)statistic_viewer_data->stats); + + reg_update_time_window(statistic_update_time_window,statistic_viewer_data, statistic_viewer_data->mw); + reg_show_viewer(statistic_show_viewer,statistic_viewer_data, statistic_viewer_data->mw); + reg_update_traceset(statistic_traceset_changed,statistic_viewer_data, statistic_viewer_data->mw); + + statistic_viewer_data->statistic_hash = g_hash_table_new_full(g_str_hash, g_str_equal, + statistic_destroy_hash_key, + statistic_destroy_hash_data); + + statistic_viewer_data->hpaned_v = gtk_hpaned_new(); + statistic_viewer_data->store_m = gtk_tree_store_new (N_COLUMNS, G_TYPE_STRING); + statistic_viewer_data->tree_v = gtk_tree_view_new_with_model (GTK_TREE_MODEL (statistic_viewer_data->store_m)); + g_object_unref (G_OBJECT (statistic_viewer_data->store_m)); + + g_signal_connect (G_OBJECT (statistic_viewer_data->tree_v), "grab-focus", + G_CALLBACK (grab_focus), + statistic_viewer_data); + + // Setup the selection handler + statistic_viewer_data->select_c = gtk_tree_view_get_selection (GTK_TREE_VIEW (statistic_viewer_data->tree_v)); + gtk_tree_selection_set_mode (statistic_viewer_data->select_c, GTK_SELECTION_SINGLE); + g_signal_connect (G_OBJECT (statistic_viewer_data->select_c), "changed", + G_CALLBACK (tree_selection_changed_cb), + statistic_viewer_data); + + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ("Statistic Name", + renderer, + "text", NAME_COLUMN, + NULL); + gtk_tree_view_column_set_alignment (column, 0.0); + // gtk_tree_view_column_set_fixed_width (column, 45); + gtk_tree_view_append_column (GTK_TREE_VIEW (statistic_viewer_data->tree_v), column); + + + gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (statistic_viewer_data->tree_v), FALSE); + + statistic_viewer_data->scroll_win_tree = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(statistic_viewer_data->scroll_win_tree), + GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC); + + gtk_container_add (GTK_CONTAINER (statistic_viewer_data->scroll_win_tree), statistic_viewer_data->tree_v); + gtk_paned_pack1(GTK_PANED(statistic_viewer_data->hpaned_v),statistic_viewer_data->scroll_win_tree, TRUE, FALSE); + gtk_paned_set_position(GTK_PANED(statistic_viewer_data->hpaned_v), 160); + + statistic_viewer_data->scroll_win_text = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(statistic_viewer_data->scroll_win_text), + GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC); + + statistic_viewer_data->text_v = gtk_text_view_new (); + g_signal_connect (G_OBJECT (statistic_viewer_data->text_v), "grab-focus", + G_CALLBACK (grab_focus), + statistic_viewer_data); + + gtk_text_view_set_editable(GTK_TEXT_VIEW(statistic_viewer_data->text_v),FALSE); + gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(statistic_viewer_data->text_v),FALSE); + gtk_container_add (GTK_CONTAINER (statistic_viewer_data->scroll_win_text), statistic_viewer_data->text_v); + gtk_paned_pack2(GTK_PANED(statistic_viewer_data->hpaned_v), statistic_viewer_data->scroll_win_text, TRUE, FALSE); + + gtk_widget_show(statistic_viewer_data->scroll_win_tree); + gtk_widget_show(statistic_viewer_data->scroll_win_text); + gtk_widget_show(statistic_viewer_data->tree_v); + gtk_widget_show(statistic_viewer_data->text_v); + gtk_widget_show(statistic_viewer_data->hpaned_v); + + //get the life span of the traceset and set the upper of the scroll bar + get_traceset_time_span(statistic_viewer_data->mw, &statistic_viewer_data->time_span); + + statistic_viewer_data->shown = FALSE; + statistic_viewer_data->filter_key = g_strdup(key); + g_object_set_data( + G_OBJECT(statistic_viewer_data->hpaned_v), + statistic_viewer_data->filter_key, + s); + + g_object_set_data( + G_OBJECT(statistic_viewer_data->hpaned_v), + TRACESET_TIME_SPAN, + &statistic_viewer_data->time_span); + + if(statistic_viewer_data->calculate_stats){ + if(lttv_stats_load_statistics(statistic_viewer_data->stats)) + statistic_viewer_data->calculate_stats = FALSE; + } + + if(statistic_viewer_data->calculate_stats == FALSE){ + statistic_viewer_data->size = 1; + g_object_set_data( + G_OBJECT(statistic_viewer_data->hpaned_v), + MAX_NUMBER_EVENT, + &statistic_viewer_data->size); + } + + g_object_set_data_full( + G_OBJECT(statistic_viewer_data->hpaned_v), + "statistic_viewer_data", + statistic_viewer_data, + (GDestroyNotify)gui_statistic_free); + + /* Add the object's information to the module's array */ + g_statistic_viewer_data_list = g_slist_append( + g_statistic_viewer_data_list, + statistic_viewer_data); + + return statistic_viewer_data; +} + +void grab_focus(GtkWidget *widget, gpointer data) +{ + StatisticViewerData *statistic_viewer_data = (StatisticViewerData *)data; + MainWindow * mw = statistic_viewer_data->mw; + set_focused_pane(mw, gtk_widget_get_parent(statistic_viewer_data->hpaned_v)); +} + +static void +tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data) +{ + StatisticViewerData *statistic_viewer_data = (StatisticViewerData*)data; + GtkTreeIter iter; + GtkTreeModel *model = GTK_TREE_MODEL(statistic_viewer_data->store_m); + gchar *event; + GtkTextBuffer* buf; + gchar * str; + GtkTreePath * path; + GtkTextIter text_iter; + LttvAttribute * stats; + + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + { + gtk_tree_model_get (model, &iter, NAME_COLUMN, &event, -1); + + path = gtk_tree_model_get_path(GTK_TREE_MODEL(model),&iter); + str = gtk_tree_path_to_string (path); + stats = (LttvAttribute*)g_hash_table_lookup (statistic_viewer_data->statistic_hash,str); + g_free(str); + + buf = gtk_text_view_get_buffer((GtkTextView*)statistic_viewer_data->text_v); + gtk_text_buffer_set_text(buf,"Statistic for '", -1); + gtk_text_buffer_get_end_iter(buf, &text_iter); + gtk_text_buffer_insert(buf, &text_iter, event, strlen(event)); + gtk_text_buffer_get_end_iter(buf, &text_iter); + gtk_text_buffer_insert(buf, &text_iter, "' :\n\n",5); + + show_statistic(statistic_viewer_data, stats, buf); + + g_free (event); + } +} + +void statistic_destroy_hash_key(gpointer key) +{ + g_free(key); +} + +void statistic_destroy_hash_data(gpointer data) +{ + // g_free(data); +} + +void show_traceset_stats(StatisticViewerData * statistic_viewer_data) +{ + int i, nb; + LttvTraceset *ts; + LttvTraceStats *tcs; + LttSystemDescription *desc; + LttvTracesetStats * tscs = statistic_viewer_data->stats; + gchar * str, trace_str[PATH_LENGTH]; + GtkTreePath * path; + GtkTreeIter iter; + GtkTreeStore * store = statistic_viewer_data->store_m; + + if(tscs->stats == NULL) return; + + gtk_tree_store_append (store, &iter, NULL); + gtk_tree_store_set (store, &iter, + NAME_COLUMN, "Traceset statistics", + -1); + path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter); + str = gtk_tree_path_to_string (path); + g_hash_table_insert(statistic_viewer_data->statistic_hash, + (gpointer)str, tscs->stats); + show_tree(statistic_viewer_data, tscs->stats, &iter); + + //show stats for all traces + ts = tscs->parent.parent.ts; + nb = lttv_traceset_number(ts); + + for(i = 0 ; i < nb ; i++) { + tcs = (LttvTraceStats *)(LTTV_TRACESET_CONTEXT(tscs)->traces[i]); + desc = ltt_trace_system_description(tcs->parent.parent.t); + sprintf(trace_str, "Trace on system %s at time %d secs", + ltt_trace_system_description_node_name(desc), + (ltt_trace_system_description_trace_start_time(desc)).tv_sec); + + gtk_tree_store_append (store, &iter, NULL); + gtk_tree_store_set (store, &iter,NAME_COLUMN,trace_str,-1); + path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter); + str = gtk_tree_path_to_string (path); + g_hash_table_insert(statistic_viewer_data->statistic_hash, + (gpointer)str,tcs->stats); + show_tree(statistic_viewer_data, tcs->stats, &iter); + } +} + +void show_tree(StatisticViewerData * statistic_viewer_data, + LttvAttribute* stats, GtkTreeIter* parent) +{ + int i, nb; + LttvAttribute *subtree; + LttvAttributeName name; + LttvAttributeValue value; + LttvAttributeType type; + gchar * str, dir_str[PATH_LENGTH]; + GtkTreePath * path; + GtkTreeIter iter; + GtkTreeStore * store = statistic_viewer_data->store_m; + + nb = lttv_attribute_get_number(stats); + for(i = 0 ; i < nb ; i++) { + type = lttv_attribute_get(stats, i, &name, &value); + switch(type) { + case LTTV_GOBJECT: + if(LTTV_IS_ATTRIBUTE(*(value.v_gobject))) { + sprintf(dir_str, "%s", g_quark_to_string(name)); + subtree = (LttvAttribute *)*(value.v_gobject); + gtk_tree_store_append (store, &iter, parent); + gtk_tree_store_set (store, &iter,NAME_COLUMN,dir_str,-1); + path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter); + str = gtk_tree_path_to_string (path); + g_hash_table_insert(statistic_viewer_data->statistic_hash, + (gpointer)str, subtree); + show_tree(statistic_viewer_data, subtree, &iter); + } + break; + default: + break; + } + } +} + +void show_statistic(StatisticViewerData * statistic_viewer_data, + LttvAttribute* stats, GtkTextBuffer* buf) +{ + int i, nb , flag; + LttvAttribute *subtree; + LttvAttributeName name; + LttvAttributeValue value; + LttvAttributeType type; + gchar type_name[PATH_LENGTH], type_value[PATH_LENGTH]; + GtkTextIter text_iter; + + flag = 0; + nb = lttv_attribute_get_number(stats); + for(i = 0 ; i < nb ; i++) { + type = lttv_attribute_get(stats, i, &name, &value); + sprintf(type_name,"%s", g_quark_to_string(name)); + type_value[0] = '\0'; + switch(type) { + case LTTV_INT: + sprintf(type_value, " : %d\n", *value.v_int); + break; + case LTTV_UINT: + sprintf(type_value, " : %u\n", *value.v_uint); + break; + case LTTV_LONG: + sprintf(type_value, " : %ld\n", *value.v_long); + break; + case LTTV_ULONG: + sprintf(type_value, " : %lu\n", *value.v_ulong); + break; + case LTTV_FLOAT: + sprintf(type_value, " : %f\n", (double)*value.v_float); + break; + case LTTV_DOUBLE: + sprintf(type_value, " : %f\n", *value.v_double); + break; + case LTTV_TIME: + sprintf(type_value, " : %10u.%09u\n", value.v_time->tv_sec, + value.v_time->tv_nsec); + break; + case LTTV_POINTER: + sprintf(type_value, " : POINTER\n"); + break; + case LTTV_STRING: + sprintf(type_value, " : %s\n", *value.v_string); + break; + default: + break; + } + if(strlen(type_value)){ + flag = 1; + strcat(type_name,type_value); + gtk_text_buffer_get_end_iter(buf, &text_iter); + gtk_text_buffer_insert(buf, &text_iter, type_name, strlen(type_name)); + } + } + + if(flag == 0){ + sprintf(type_value, "No statistic information in this directory.\nCheck in subdirectories please.\n"); + gtk_text_buffer_get_end_iter(buf, &text_iter); + gtk_text_buffer_insert(buf, &text_iter, type_value, strlen(type_value)); + + } +} + +gboolean statistic_update_time_window(void * hook_data, void * call_data) +{ + StatisticViewerData *statistic_viewer_data = (StatisticViewerData*) hook_data; + LttvTracesetContext * tsc = get_traceset_context(statistic_viewer_data->mw); + + //if statistic is already calculated, do nothing + if(!statistic_viewer_data->calculate_stats){ + return FALSE; + } + + if(statistic_viewer_data->shown == FALSE){ + statistic_add_context_hooks(statistic_viewer_data, tsc); + } + return FALSE; +} + +gboolean statistic_show_viewer(void * hook_data, void * call_data) +{ + StatisticViewerData *statistic_viewer_data = (StatisticViewerData*) hook_data; + LttvTracesetContext * tsc = get_traceset_context(statistic_viewer_data->mw); + + if(statistic_viewer_data->shown == FALSE){ + statistic_viewer_data->shown = TRUE; + show_traceset_stats(statistic_viewer_data); + if(statistic_viewer_data->calculate_stats){ + statistic_remove_context_hooks(statistic_viewer_data,tsc); + lttv_stats_save_statistics((LttvTracesetStats*)tsc); + } + } + + return FALSE; +} + +gboolean statistic_traceset_changed(void * hook_data, void * call_data) +{ + StatisticViewerData *statistic_viewer_data = (StatisticViewerData*) hook_data; + + // gtk_tree_store_clear (statistic_viewer_data->store_m); + // statistic_viewer_data->shown = FALSE; + + return FALSE; +} + +void statistic_add_context_hooks(StatisticViewerData * statistic_viewer_data, + LttvTracesetContext * tsc) +{ + gint i, j, nbi, nb_tracefile, nb_control, nb_per_cpu; + LttTrace *trace; + LttvTraceContext *tc; + LttvTracefileContext *tfc; + LttvTracesetSelector * ts_s; + LttvTraceSelector * t_s; + LttvTracefileSelector * tf_s; + gboolean selected; + + ts_s = (LttvTracesetSelector*)g_object_get_data(G_OBJECT(statistic_viewer_data->hpaned_v), + statistic_viewer_data->filter_key); + + //if there are hooks for traceset, add them here + + nbi = lttv_traceset_number(tsc->ts); + for(i = 0 ; i < nbi ; i++) { + t_s = lttv_traceset_selector_trace_get(ts_s,i); + selected = lttv_trace_selector_get_selected(t_s); + if(!selected) continue; + tc = tsc->traces[i]; + trace = tc->t; + //if there are hooks for trace, add them here + + nb_control = ltt_trace_control_tracefile_number(trace); + nb_per_cpu = ltt_trace_per_cpu_tracefile_number(trace); + nb_tracefile = nb_control + nb_per_cpu; + + for(j = 0 ; j < nb_tracefile ; j++) { + tf_s = lttv_trace_selector_tracefile_get(t_s,j); + selected = lttv_tracefile_selector_get_selected(tf_s); + if(!selected) continue; + + if(j < nb_control) + tfc = tc->control_tracefiles[j]; + else + tfc = tc->per_cpu_tracefiles[j - nb_control]; + + //if there are hooks for tracefile, add them here + // lttv_tracefile_context_add_hooks(tfc, NULL,NULL,NULL,NULL, + // statistic_viewer_data->before_event_hooks,NULL); + } + } + + //add state and stats hooks + //state_add_event_hooks_api(statistic_viewer_data->mw); //it will be added in the main window + stats_add_event_hooks_api(statistic_viewer_data->mw); + +} + +void statistic_remove_context_hooks(StatisticViewerData * statistic_viewer_data, + LttvTracesetContext * tsc) +{ + gint i, j, nbi, nb_tracefile, nb_control, nb_per_cpu; + LttTrace *trace; + LttvTraceContext *tc; + LttvTracefileContext *tfc; + LttvTracesetSelector * ts_s; + LttvTraceSelector * t_s; + LttvTracefileSelector * tf_s; + gboolean selected; + + ts_s = (LttvTracesetSelector*)g_object_get_data(G_OBJECT(statistic_viewer_data->hpaned_v), + statistic_viewer_data->filter_key); + + //if there are hooks for traceset, remove them here + + nbi = lttv_traceset_number(tsc->ts); + for(i = 0 ; i < nbi ; i++) { + t_s = lttv_traceset_selector_trace_get(ts_s,i); + selected = lttv_trace_selector_get_selected(t_s); + if(!selected) continue; + tc = tsc->traces[i]; + trace = tc->t; + //if there are hooks for trace, remove them here + + nb_control = ltt_trace_control_tracefile_number(trace); + nb_per_cpu = ltt_trace_per_cpu_tracefile_number(trace); + nb_tracefile = nb_control + nb_per_cpu; + + for(j = 0 ; j < nb_tracefile ; j++) { + tf_s = lttv_trace_selector_tracefile_get(t_s,j); + selected = lttv_tracefile_selector_get_selected(tf_s); + if(!selected) continue; + + if(j < nb_control) + tfc = tc->control_tracefiles[j]; + else + tfc = tc->per_cpu_tracefiles[j - nb_control]; + + //if there are hooks for tracefile, remove them here + // lttv_tracefile_context_remove_hooks(tfc, NULL,NULL,NULL,NULL, + // statistic_viewer_data->before_event_hooks,NULL); + } + } + + //remove state and stats hooks + //state_remove_event_hooks_api(statistic_viewer_data->mw); //it will be done in the main window + stats_remove_event_hooks_api(statistic_viewer_data->mw); +} + + diff --git a/ltt/branches/poly/lttv/modules/guiControlFlow/CFV-private.h b/ltt/branches/poly/lttv/modules/guiControlFlow/CFV-private.h deleted file mode 100644 index 2903a281..00000000 --- a/ltt/branches/poly/lttv/modules/guiControlFlow/CFV-private.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _CFV_PRIVATE_H -#define _CFV_PRIVATE_H - - - -struct _ControlFlowData { - - GtkWidget *scrolled_window; - MainWindow *mw; - - ProcessList *process_list; - Drawing_t *drawing; - - GtkWidget *h_paned; - - GtkAdjustment *v_adjust ; - - /* Shown events information */ - TimeWindow time_window; - LttTime current_time; - - //guint currently_Selected_Event ; - guint number_of_process; - -} ; - - -#endif //_CFV_PRIVATE_H diff --git a/ltt/branches/poly/lttv/modules/guiControlFlow/CFV.c b/ltt/branches/poly/lttv/modules/guiControlFlow/CFV.c deleted file mode 100644 index ac371adc..00000000 --- a/ltt/branches/poly/lttv/modules/guiControlFlow/CFV.c +++ /dev/null @@ -1,173 +0,0 @@ - -#include -#include -#include - -#include "CFV.h" -#include "Drawing.h" -#include "Process_List.h" -#include "Event_Hooks.h" -#include "CFV-private.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) - -extern GSList *g_control_flow_data_list; - -/***************************************************************************** - * Control Flow Viewer class implementation * - *****************************************************************************/ -/** - * 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. - */ -ControlFlowData * -guicontrolflow(void) -{ - GtkWidget *process_list_widget, *drawing_widget; - - ControlFlowData* control_flow_data = g_new(ControlFlowData,1) ; - - /* Create the drawing */ - control_flow_data->drawing = drawing_construct(control_flow_data); - - drawing_widget = - drawing_get_widget(control_flow_data->drawing); - - control_flow_data->number_of_process = 0; - - /* Create the Process list */ - control_flow_data->process_list = processlist_construct(); - - process_list_widget = - processlist_get_widget(control_flow_data->process_list); - - //control_flow_data->Inside_HBox_V = gtk_hbox_new(0, 0); - control_flow_data->h_paned = gtk_hpaned_new(); - - gtk_paned_pack1(GTK_PANED(control_flow_data->h_paned), process_list_widget, FALSE, TRUE); - gtk_paned_pack2(GTK_PANED(control_flow_data->h_paned), drawing_widget, TRUE, TRUE); - - 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 */ - - control_flow_data->scrolled_window = - gtk_scrolled_window_new (NULL, - control_flow_data->v_adjust); - - gtk_scrolled_window_set_policy( - GTK_SCROLLED_WINDOW(control_flow_data->scrolled_window) , - GTK_POLICY_NEVER, - GTK_POLICY_AUTOMATIC); - - gtk_scrolled_window_add_with_viewport( - GTK_SCROLLED_WINDOW(control_flow_data->scrolled_window), - control_flow_data->h_paned); - - /* Set the size of the drawing area */ - //drawing_Resize(drawing, h, w); - - /* Get trace statistics */ - //control_flow_data->Trace_Statistics = get_trace_statistics(Trace); - - - gtk_widget_show(drawing_widget); - gtk_widget_show(process_list_widget); - gtk_widget_show(control_flow_data->h_paned); - gtk_widget_show(control_flow_data->scrolled_window); - - g_object_set_data_full( - G_OBJECT(control_flow_data->scrolled_window), - "control_flow_data", - control_flow_data, - (GDestroyNotify)guicontrolflow_destructor); - - g_object_set_data( - G_OBJECT(drawing_widget), - "control_flow_data", - control_flow_data); - - g_control_flow_data_list = g_slist_append( - g_control_flow_data_list, - control_flow_data); - - //WARNING : The widget must be - //inserted in the main window before the drawing area - //can be configured (and this must happend bedore sending - //data) - - return control_flow_data; - -} - -/* Destroys widget also */ -void -guicontrolflow_destructor_full(ControlFlowData *control_flow_data) -{ - g_info("CFV.c : guicontrolflow_destructor_full, %p", control_flow_data); - /* May already have been done by GTK window closing */ - if(GTK_IS_WIDGET(control_flow_data->scrolled_window)) - gtk_widget_destroy(control_flow_data->scrolled_window); - //control_flow_data->mw = NULL; - //FIXME guicontrolflow_destructor(control_flow_data); -} - -/* When this destructor is called, the widgets are already disconnected */ -void -guicontrolflow_destructor(ControlFlowData *control_flow_data) -{ - guint index; - - g_info("CFV.c : guicontrolflow_destructor, %p", control_flow_data); - g_info("%p, %p, %p", update_time_window_hook, control_flow_data, control_flow_data->mw); - if(GTK_IS_WIDGET(control_flow_data->scrolled_window)) - g_info("widget still exists"); - - /* Process List is removed with it's widget */ - //ProcessList_destroy(control_flow_data->process_list); - if(control_flow_data->mw != NULL) - { - unreg_update_time_window(update_time_window_hook, - control_flow_data, - control_flow_data->mw); - - unreg_update_current_time(update_current_time_hook, - control_flow_data, - control_flow_data->mw); - } - g_info("CFV.c : guicontrolflow_destructor, %p", control_flow_data); - g_slist_remove(g_control_flow_data_list,control_flow_data); - g_free(control_flow_data); -} - -GtkWidget *guicontrolflow_get_widget(ControlFlowData *control_flow_data) -{ - return control_flow_data->scrolled_window ; -} - -ProcessList *guicontrolflow_get_process_list - (ControlFlowData *control_flow_data) -{ - return control_flow_data->process_list ; -} - -TimeWindow *guicontrolflow_get_time_window(ControlFlowData *control_flow_data) -{ - return &control_flow_data->time_window; -} -LttTime *guicontrolflow_get_current_time(ControlFlowData *control_flow_data) -{ - return &control_flow_data->current_time; -} - - diff --git a/ltt/branches/poly/lttv/modules/guiControlFlow/CFV.h b/ltt/branches/poly/lttv/modules/guiControlFlow/CFV.h deleted file mode 100644 index 208cbf7e..00000000 --- a/ltt/branches/poly/lttv/modules/guiControlFlow/CFV.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _CFV_H -#define _CFV_H - -#include -#include -#include -#include "Process_List.h" - -typedef struct _ControlFlowData ControlFlowData; - -/* Control Flow Data constructor */ -ControlFlowData *guicontrolflow(void); -void -guicontrolflow_destructor_full(ControlFlowData *control_flow_data); -void -guicontrolflow_destructor(ControlFlowData *control_flow_data); -GtkWidget *guicontrolflow_get_widget(ControlFlowData *control_flow_data); -ProcessList *guicontrolflow_get_process_list(ControlFlowData *control_flow_data); -TimeWindow *guicontrolflow_get_time_window(ControlFlowData *control_flow_data); -LttTime *guicontrolflow_get_current_time(ControlFlowData *control_flow_data); - - -#endif // _CFV_H diff --git a/ltt/branches/poly/lttv/modules/guiControlFlow/Draw_Item.c b/ltt/branches/poly/lttv/modules/guiControlFlow/Draw_Item.c deleted file mode 100644 index 7c929c82..00000000 --- a/ltt/branches/poly/lttv/modules/guiControlFlow/Draw_Item.c +++ /dev/null @@ -1,345 +0,0 @@ -/****************************************************************************** - * Draw_Item.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 - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "Draw_Item.h" - - -#define MAX_PATH_LEN 256 - -/* drawing hook functions */ -gboolean draw_text( void *hook_data, void *call_data) -{ - PropertiesText *Properties = (PropertiesText*)hook_data; - DrawContext *Draw_Context = (DrawContext*)call_data; - - PangoContext *context; - PangoLayout *layout; - PangoAttribute *attribute; - PangoFontDescription *FontDesc;// = pango_font_description_new(); - gint Font_Size; - PangoRectangle ink_rect; - - layout = Draw_Context->pango_layout; - - context = pango_layout_get_context(layout); - FontDesc = pango_context_get_font_description(context); - - pango_font_description_set_size(FontDesc, 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); - switch(Properties->position) { - case OVER: - gdk_draw_layout_with_colors(Draw_Context->drawable, - Draw_Context->gc, - Draw_Context->current->modify_over->x, - Draw_Context->current->modify_over->y, - layout, Properties->foreground, Properties->background); - Draw_Context->current->modify_over->x += ink_rect.width; - - break; - case MIDDLE: - gdk_draw_layout_with_colors(Draw_Context->drawable, - Draw_Context->gc, - Draw_Context->current->modify_middle->x, - Draw_Context->current->modify_middle->y, - layout, Properties->foreground, Properties->background); - Draw_Context->current->modify_middle->x += ink_rect.width; - break; - case UNDER: - gdk_draw_layout_with_colors(Draw_Context->drawable, - Draw_Context->gc, - Draw_Context->current->modify_under->x, - Draw_Context->current->modify_under->y, - layout, Properties->foreground, Properties->background); - Draw_Context->current->modify_under->x += ink_rect.width; - break; - } - - return 0; -} - - -/* To speed up the process, search in already loaded icons list first. Only - * load it if not present. - */ -gboolean draw_icon( void *hook_data, void *call_data) -{ - PropertiesIcon *Properties = (PropertiesIcon*)hook_data; - DrawContext *Draw_Context = (DrawContext*)call_data; - - LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes()); - LttvAttributeValue value; - gchar icon_name[MAX_PATH_LEN] = "icons/"; - IconStruct *icon_info; - - strcat(icon_name, Properties->icon_name); - - g_assert(lttv_iattribute_find_by_path(attributes, icon_name, - LTTV_POINTER, &value)); - if(*(value.v_pointer) == NULL) - { - *(value.v_pointer) = icon_info = g_new(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); - } - - gdk_gc_set_clip_mask(Draw_Context->gc, icon_info->mask); - - switch(Properties->position) { - case OVER: - gdk_gc_set_clip_origin( - Draw_Context->gc, - Draw_Context->current->modify_over->x, - Draw_Context->current->modify_over->y); - gdk_draw_drawable(Draw_Context->drawable, - Draw_Context->gc, - icon_info->pixmap, - 0, 0, - Draw_Context->current->modify_over->x, - Draw_Context->current->modify_over->y, - Properties->width, Properties->height); - - Draw_Context->current->modify_over->x += Properties->width; - - break; - case MIDDLE: - gdk_gc_set_clip_origin( - Draw_Context->gc, - Draw_Context->current->modify_middle->x, - Draw_Context->current->modify_middle->y); - gdk_draw_drawable(Draw_Context->drawable, - Draw_Context->gc, - icon_info->pixmap, - 0, 0, - Draw_Context->current->modify_middle->x, - Draw_Context->current->modify_middle->y, - Properties->width, Properties->height); - - Draw_Context->current->modify_middle->x += Properties->width; - break; - case UNDER: - gdk_gc_set_clip_origin( - Draw_Context->gc, - Draw_Context->current->modify_under->x, - Draw_Context->current->modify_under->y); - gdk_draw_drawable(Draw_Context->drawable, - Draw_Context->gc, - icon_info->pixmap, - 0, 0, - Draw_Context->current->modify_under->x, - Draw_Context->current->modify_under->y, - Properties->width, Properties->height); - - Draw_Context->current->modify_under->x += Properties->width; - break; - } - - gdk_gc_set_clip_origin(Draw_Context->gc, 0, 0); - gdk_gc_set_clip_mask(Draw_Context->gc, NULL); - - return 0; -} - -gboolean draw_line( void *hook_data, void *call_data) -{ - PropertiesLine *Properties = (PropertiesLine*)hook_data; - DrawContext *Draw_Context = (DrawContext*)call_data; - //GdkGC *gc = gdk_gc_new(Draw_Context->drawable); - - //gdk_gc_set_foreground(Draw_Context->gc, Properties->color); - gdk_gc_set_rgb_fg_color(Draw_Context->gc, Properties->color); - //gdk_gc_set_foreground(gc, Properties->color); - gdk_gc_set_line_attributes( Draw_Context->gc, - Properties->line_width, - Properties->style, - GDK_CAP_BUTT, - GDK_JOIN_MITER); - - switch(Properties->position) { - case OVER: - drawing_draw_line( - NULL, Draw_Context->drawable, - Draw_Context->previous->over->x, - Draw_Context->previous->over->y, - Draw_Context->current->over->x, - Draw_Context->current->over->y, - Draw_Context->gc); - break; - case MIDDLE: - drawing_draw_line( - NULL, Draw_Context->drawable, - Draw_Context->previous->middle->x, - Draw_Context->previous->middle->y, - Draw_Context->current->middle->x, - Draw_Context->current->middle->y, - Draw_Context->gc); - break; - case UNDER: - drawing_draw_line( - NULL, Draw_Context->drawable, - Draw_Context->previous->under->x, - Draw_Context->previous->under->y, - Draw_Context->current->under->x, - Draw_Context->current->under->y, - Draw_Context->gc); - - break; - } - - //gdk_gc_unref(gc); - - return 0; -} - -gboolean draw_arc( void *hook_data, void *call_data) -{ - PropertiesArc *Properties = (PropertiesArc*)hook_data; - DrawContext *Draw_Context = (DrawContext*)call_data; - - //gdk_gc_set_foreground(Draw_Context->gc, Properties->color); - gdk_gc_set_rgb_fg_color(Draw_Context->gc, Properties->color); - - switch(Properties->position) { - case OVER: - gdk_draw_arc(Draw_Context->drawable, Draw_Context->gc, - Properties->filled, - Draw_Context->current->modify_over->x, - Draw_Context->current->modify_over->y, - Properties->size, Properties->size, 0, 360*64); - Draw_Context->current->modify_over->x += Properties->size; - break; - case MIDDLE: - gdk_draw_arc(Draw_Context->drawable, Draw_Context->gc, - Properties->filled, - Draw_Context->current->modify_middle->x, - Draw_Context->current->modify_middle->y, - Properties->size, Properties->size, 0, 360*64); - Draw_Context->current->modify_middle->x += Properties->size; - - break; - case UNDER: - gdk_draw_arc(Draw_Context->drawable, Draw_Context->gc, - Properties->filled, - Draw_Context->current->modify_under->x, - Draw_Context->current->modify_under->y, - Properties->size, Properties->size, 0, 360*64); - Draw_Context->current->modify_under->x += Properties->size; - - break; - } - - - return 0; -} - -gboolean draw_bg( void *hook_data, void *call_data) -{ - PropertiesBG *Properties = (PropertiesBG*)hook_data; - DrawContext *Draw_Context = (DrawContext*)call_data; - - //gdk_gc_set_foreground(Draw_Context->gc, Properties->color); - gdk_gc_set_rgb_fg_color(Draw_Context->gc, Properties->color); - - - gdk_draw_rectangle(Draw_Context->drawable, Draw_Context->gc, - TRUE, - Draw_Context->previous->over->x, - Draw_Context->previous->over->y, - Draw_Context->current->over->x - Draw_Context->previous->over->x, - Draw_Context->previous->under->y); - - return 0; -} - - diff --git a/ltt/branches/poly/lttv/modules/guiControlFlow/Draw_Item.h b/ltt/branches/poly/lttv/modules/guiControlFlow/Draw_Item.h deleted file mode 100644 index 9f342052..00000000 --- a/ltt/branches/poly/lttv/modules/guiControlFlow/Draw_Item.h +++ /dev/null @@ -1,283 +0,0 @@ -#ifndef _DRAW_ITEM_H -#define _DRAW_ITEM_H - -#include - -typedef struct _DrawContext DrawContext; -typedef struct _DrawInfo DrawInfo; -typedef struct _ItemInfo ItemInfo; - -typedef struct _IconStruct IconStruct; - -typedef struct _DrawOperation DrawOperation; - - -typedef struct _PropertiesText PropertiesText; -typedef struct _PropertiesIcon PropertiesIcon; -typedef struct _PropertiesLine PropertiesLine; -typedef struct _PropertiesArc PropertiesArc; -typedef struct _PropertiesBG PropertiesBG; - -typedef enum _DrawableItems DrawableItems; -enum _DrawableItems { - ITEM_TEXT, ITEM_ICON, ITEM_LINE, ITEM_POINT, ITEM_BACKGROUND -}; - - -typedef enum _RelPos { - OVER, MIDDLE, UNDER -} RelPos; - - -/* 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. - * - */ - - -struct _DrawContext { - GdkDrawable *drawable; - GdkGC *gc; - PangoLayout *pango_layout; - - DrawInfo *current; - DrawInfo *previous; -}; - -/* LttvExecutionState is accessible through the LttvTracefileState. Is has - * a pointer to the LttvProcessState which points to the top of stack - * execution state : LttvExecutionState *state. - * - * LttvExecutionState contains (useful here): - * LttvExecutionMode t, - * LttvExecutionSubmode n, - * LttvProcessStatus s - * - * - * LttvTraceState will be used in the case we need the string of the - * different processes, eventtype_names, syscall_names, trap_names, irq_names. - * - * LttvTracefileState also gives the cpu_name and, as it herits from - * LttvTracefileContext, it gives the LttEvent structure, which is needed - * to get facility name and event name. - */ -struct _DrawInfo { - ItemInfo *over; - ItemInfo *middle; - ItemInfo *under; - - ItemInfo *modify_over; - ItemInfo *modify_middle; - ItemInfo *modify_under; - LttvProcessStatus status; -}; - -struct _ItemInfo { - gint x, y; -}; - -/* - * Structure used to keep information about icons. - */ -struct _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 _DrawOperation { - DrawableItems item; - LttvHooks *hook; -}; - -/* - * 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 */ -}; - -/* - * 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 _PropertiesText { - GdkColor *foreground; - GdkColor *background; - gint size; - gchar *text; - RelPos position; -}; - - -struct _PropertiesIcon { - gchar *icon_name; - gint width; - gint height; - RelPos position; -}; - -struct _PropertiesLine { - GdkColor *color; - gint line_width; - GdkLineStyle style; - RelPos position; -}; - -struct _PropertiesArc { - GdkColor *color; - gint size; /* We force circle by width = height */ - gboolean filled; - RelPos position; -}; - -struct _PropertiesBG { - GdkColor *color; -}; - - - -void 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" - */ - -/* - * 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); - - -/* - * Functions to create Properties structures. - */ - -PropertiesText *properties_text_create( - GdkColor *foreground, - GdkColor *background, - gint size, - gchar *text, - RelPos position); - -PropertiesIcon *properties_icon_create( - gchar *icon_name, - gint width, - gint height, - RelPos position); - -PropertiesLine *properties_line_create( - GdkColor *color, - gint line_width, - GdkLineStyle style, - RelPos position); - -PropertiesArc *properties_arc_create( - GdkColor *color, - gint size, - gboolean filled, - RelPos position); - -PropertiesBG *properties_bg_create( - GdkColor *color); - - - - -/* - * Here follow the prototypes of the hook functions used to draw the - * different items. - */ - -gboolean draw_text( void *hook_data, void *call_data); -gboolean draw_icon( void *hook_data, void *call_data); -gboolean draw_line( void *hook_data, void *call_data); -gboolean draw_arc( void *hook_data, void *call_data); -gboolean draw_bg( void *hook_data, void *call_data); - - -#endif // _DRAW_ITEM_H diff --git a/ltt/branches/poly/lttv/modules/guiControlFlow/Drawing.c b/ltt/branches/poly/lttv/modules/guiControlFlow/Drawing.c deleted file mode 100644 index 85d2efcb..00000000 --- a/ltt/branches/poly/lttv/modules/guiControlFlow/Drawing.c +++ /dev/null @@ -1,640 +0,0 @@ - -#include -#include - -#include -#include -#include - -#include "Drawing.h" -#include "CFV.h" -#include "CFV-private.h" -#include "Event_Hooks.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) - -/***************************************************************************** - * drawing functions * - *****************************************************************************/ - -//FIXME Colors will need to be dynamic. Graphic context part not done so far. -typedef enum -{ - RED, - GREEN, - BLUE, - WHITE, - BLACK - -} ControlFlowColors; - -/* Vector of unallocated colors */ -static GdkColor CF_Colors [] = -{ - { 0, 0xffff, 0x0000, 0x0000 }, // RED - { 0, 0x0000, 0xffff, 0x0000 }, // GREEN - { 0, 0x0000, 0x0000, 0xffff }, // BLUE - { 0, 0xffff, 0xffff, 0xffff }, // WHITE - { 0, 0x0000, 0x0000, 0x0000 } // BLACK -}; - - -/* Function responsible for updating the exposed area. - * It must call processTrace() to ask for this update. - * Note : this function cannot clear the background, because it may - * erase drawing already present (SAFETY). - */ -void drawing_data_request(Drawing_t *drawing, - GdkPixmap **pixmap, - gint x, gint y, - gint width, - gint height) -{ - if(width < 0) return ; - if(height < 0) return ; - ControlFlowData *control_flow_data = - (ControlFlowData*)g_object_get_data( - G_OBJECT( - drawing->drawing_area), - "control_flow_data"); - - LttTime start, end; - LttTime window_end = ltt_time_add(control_flow_data->time_window.time_width, - control_flow_data->time_window.start_time); - - g_critical("req : window_end : %u, %u", window_end.tv_sec, - window_end.tv_nsec); - - g_critical("req : time width : %u, %u", control_flow_data->time_window.time_width.tv_sec, - control_flow_data->time_window.time_width.tv_nsec); - - g_critical("x is : %i, x+width is : %i", x, x+width); - - convert_pixels_to_time(drawing->drawing_area->allocation.width, x, - &control_flow_data->time_window.start_time, - &window_end, - &start); - - convert_pixels_to_time(drawing->drawing_area->allocation.width, x + width, - &control_flow_data->time_window.start_time, - &window_end, - &end); - - LttvTracesetContext * tsc = - get_traceset_context(control_flow_data->mw); - - //send_test_process( - //guicontrolflow_get_process_list(drawing->control_flow_data), - //drawing); - //send_test_drawing( - //guicontrolflow_get_process_list(drawing->control_flow_data), - //drawing, *pixmap, x, y, width, height); - - // Let's call processTrace() !! - EventRequest event_request; // Variable freed at the end of the function. - event_request.control_flow_data = control_flow_data; - event_request.time_begin = start; - event_request.time_end = end; - event_request.x_begin = x; - event_request.x_end = x+width; - - g_critical("req : start : %u, %u", event_request.time_begin.tv_sec, - event_request.time_begin.tv_nsec); - - g_critical("req : end : %u, %u", event_request.time_end.tv_sec, - event_request.time_end.tv_nsec); - - LttvHooks *event = lttv_hooks_new(); - LttvHooks *after_event = lttv_hooks_new(); - LttvHooks *after_traceset = lttv_hooks_new(); - lttv_hooks_add(after_traceset, after_data_request, &event_request); - lttv_hooks_add(event, draw_event_hook, &event_request); - //Modified by xiangxiu: state update hooks are added by the main window - //state_add_event_hooks_api(control_flow_data->mw); - lttv_hooks_add(after_event, draw_after_hook, &event_request); - - lttv_process_traceset_seek_time(tsc, start); - // FIXME : would like to place the after_traceset hook after the traceset, - // but the traceset context state is not valid anymore. - lttv_traceset_context_add_hooks(tsc, - // NULL, after_traceset, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - NULL, after_traceset, NULL, event, after_event); - lttv_process_traceset(tsc, end, G_MAXULONG); - //after_data_request((void*)&event_request,(void*)tsc); - lttv_traceset_context_remove_hooks(tsc, - //NULL, after_traceset, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - NULL, after_traceset, NULL, event, after_event); - //Modified by xiangxiu: state update hooks are removed by the main window - //state_remove_event_hooks_api(control_flow_data->mw); - - lttv_hooks_destroy(after_traceset); - lttv_hooks_destroy(event); - lttv_hooks_destroy(after_event); - - -} - -/* 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. - */ -static gboolean -configure_event( GtkWidget *widget, GdkEventConfigure *event, - gpointer user_data) -{ - Drawing_t *drawing = (Drawing_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. - */ - get_time_window(drawing->control_flow_data->mw, - &drawing->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_critical("drawing configure event"); - g_critical("New draw size : %i by %i",widget->allocation.width, widget->allocation.height); - - - if (drawing->pixmap) - gdk_pixmap_unref(drawing->pixmap); - - /* If no old pixmap present */ - //if(drawing->pixmap == NULL) - { - drawing->pixmap = gdk_pixmap_new( - widget->window, - widget->allocation.width + SAFETY, - widget->allocation.height + SAFETY, - //ProcessList_get_height - // (GuiControlFlow_get_process_list(drawing->control_flow_data)), - -1); - drawing->width = widget->allocation.width; - drawing->height = widget->allocation.height; - - - // Clear the image - gdk_draw_rectangle (drawing->pixmap, - widget->style->white_gc, - TRUE, - 0, 0, - widget->allocation.width+SAFETY, - widget->allocation.height+SAFETY); - - //g_info("init data request"); - - - /* Initial data request */ - // Do not need to ask for data of 1 pixel : not synchronized with - // main window time at this moment. - drawing_data_request(drawing, &drawing->pixmap, 0, 0, - widget->allocation.width, - widget->allocation.height); - - drawing->width = widget->allocation.width; - drawing->height = widget->allocation.height; - - return TRUE; - - - - } -#ifdef NOTUSE -// /* Draw empty background */ -// gdk_draw_rectangle (pixmap, -// widget->style->black_gc, -// TRUE, -// 0, 0, -// widget->allocation.width, -// widget->allocation.height); - - /* Copy old data to new pixmap */ - gdk_draw_drawable (pixmap, - widget->style->white_gc, - drawing->pixmap, - 0, 0, - 0, 0, - -1, -1); - - if (drawing->pixmap) - gdk_pixmap_unref(drawing->pixmap); - - drawing->pixmap = pixmap; - - // Clear the bottom part of the image (SAFETY) - gdk_draw_rectangle (pixmap, - widget->style->white_gc, - TRUE, - 0, drawing->height+SAFETY, - drawing->width+SAFETY, // do not overlap - (widget->allocation.height) - drawing->height); - - // Clear the right part of the image (SAFETY) - gdk_draw_rectangle (pixmap, - widget->style->white_gc, - TRUE, - drawing->width+SAFETY, 0, - (widget->allocation.width) - drawing->width, // do not overlap - drawing->height+SAFETY); - - /* Clear the backgound for data request, but not SAFETY */ - gdk_draw_rectangle (pixmap, - drawing->drawing_area->style->white_gc, - TRUE, - drawing->width + SAFETY, 0, - widget->allocation.width - drawing->width, // do not overlap - widget->allocation.height+SAFETY); - - /* Request data for missing space */ - g_info("missing data request"); - drawing_data_request(drawing, &pixmap, drawing->width, 0, - widget->allocation.width - drawing->width, - widget->allocation.height); - - drawing->width = widget->allocation.width; - drawing->height = widget->allocation.height; - - return TRUE; -#endif //NOTUSE -} - - -/* Redraw the screen from the backing pixmap */ -static gboolean -expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data ) -{ - Drawing_t *drawing = (Drawing_t*)user_data; - ControlFlowData *control_flow_data = - (ControlFlowData*)g_object_get_data( - G_OBJECT(widget), - "control_flow_data"); - - g_critical("drawing expose event"); - - guint x=0; - LttTime* current_time = - guicontrolflow_get_current_time(control_flow_data); - - LttTime window_end = ltt_time_add(control_flow_data->time_window.time_width, - control_flow_data->time_window.start_time); - - convert_time_to_pixels( - control_flow_data->time_window.start_time, - window_end, - *current_time, - widget->allocation.width, - &x); - - 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); - - if(x >= event->area.x && x <= event->area.x+event->area.width) - { - GdkGC *gc = gdk_gc_new(control_flow_data->drawing->pixmap); - gdk_gc_copy(gc, widget->style->black_gc); - - drawing_draw_line(NULL, widget->window, - x, event->area.y, - x, event->area.y+event->area.height, - gc); - gdk_gc_unref(gc); - } - return FALSE; -} - -/* mouse click */ -static gboolean -button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer user_data ) -{ - ControlFlowData *control_flow_data = - (ControlFlowData*)g_object_get_data( - G_OBJECT(widget), - "control_flow_data"); - Drawing_t *drawing = control_flow_data->drawing; - - - g_critical("click"); - if(event->button == 1) - { - LttTime time; - - LttTime window_end = ltt_time_add(control_flow_data->time_window.time_width, - control_flow_data->time_window.start_time); - - - /* left mouse button click */ - g_critical("x click is : %f", event->x); - - convert_pixels_to_time(widget->allocation.width, (guint)event->x, - &control_flow_data->time_window.start_time, - &window_end, - &time); - - set_current_time(control_flow_data->mw, &time); - - } - - return FALSE; -} - - - - -Drawing_t *drawing_construct(ControlFlowData *control_flow_data) -{ - Drawing_t *drawing = g_new(Drawing_t, 1); - - drawing->drawing_area = gtk_drawing_area_new (); - drawing->control_flow_data = control_flow_data; - - drawing->pango_layout = - gtk_widget_create_pango_layout(drawing->drawing_area, NULL); - - //gtk_widget_set_size_request(drawing->drawing_area->window, 50, 50); - g_object_set_data_full( - G_OBJECT(drawing->drawing_area), - "Link_drawing_Data", - drawing, - (GDestroyNotify)drawing_destroy); - - //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); - - gtk_widget_add_events(drawing->drawing_area, GDK_BUTTON_PRESS_MASK); - - g_signal_connect (G_OBJECT(drawing->drawing_area), - "configure_event", - G_CALLBACK (configure_event), - (gpointer)drawing); - - g_signal_connect (G_OBJECT(drawing->drawing_area), - "expose_event", - G_CALLBACK (expose_event), - (gpointer)drawing); - - g_signal_connect (G_OBJECT(drawing->drawing_area), - "button-press-event", - G_CALLBACK (button_press_event), - (gpointer)drawing); - - - return drawing; -} - -void drawing_destroy(Drawing_t *drawing) -{ - - // Do not unref here, Drawing_t destroyed by it's widget. - //g_object_unref( G_OBJECT(drawing->drawing_area)); - - g_free(drawing->pango_layout); - g_free(drawing); -} - -GtkWidget *drawing_get_widget(Drawing_t *drawing) -{ - return drawing->drawing_area; -} - -/* convert_pixels_to_time - * - * Convert from window pixel and time interval to an absolute time. - */ -void convert_pixels_to_time( - gint width, - guint x, - LttTime *window_time_begin, - LttTime *window_time_end, - LttTime *time) -{ - LttTime window_time_interval; - - window_time_interval = ltt_time_sub(*window_time_end, - *window_time_begin); - *time = ltt_time_mul(window_time_interval, (x/(float)width)); - *time = ltt_time_add(*window_time_begin, *time); -} - - - -void convert_time_to_pixels( - LttTime window_time_begin, - LttTime window_time_end, - LttTime time, - int width, - guint *x) -{ - LttTime window_time_interval; - float interval_float, time_float; - - window_time_interval = ltt_time_sub(window_time_end,window_time_begin); - - time = ltt_time_sub(time, window_time_begin); - - interval_float = ltt_time_to_double(window_time_interval); - time_float = ltt_time_to_double(time); - - *x = (guint)(time_float/interval_float * width); - -} - -void drawing_refresh ( Drawing_t *drawing, - guint x, guint y, - guint width, guint height) -{ - g_info("Drawing.c : drawing_refresh %u, %u, %u, %u", x, y, width, height); - GdkRectangle update_rect; - - gdk_draw_drawable( - drawing->drawing_area->window, - drawing->drawing_area-> - style->fg_gc[GTK_WIDGET_STATE (drawing->drawing_area)], - GDK_DRAWABLE(drawing->pixmap), - x, y, - x, y, - width, height); - - update_rect.x = 0 ; - update_rect.y = 0 ; - update_rect.width = drawing->width; - update_rect.height = drawing->height ; - gtk_widget_draw( drawing->drawing_area, &update_rect); - -} - - -void drawing_draw_line( Drawing_t *drawing, - GdkPixmap *pixmap, - guint x1, guint y1, - guint x2, guint y2, - GdkGC *GC) -{ - gdk_draw_line (pixmap, - GC, - x1, y1, x2, y2); -} - - - - -void drawing_resize(Drawing_t *drawing, guint h, guint w) -{ - drawing->height = h ; - drawing->width = w ; - - gtk_widget_set_size_request ( drawing->drawing_area, - drawing->width, - drawing->height); - - -} - - -/* Insert a square corresponding to a new process in the list */ -/* Applies to whole drawing->width */ -void drawing_insert_square(Drawing_t *drawing, - guint y, - guint height) -{ - //GdkRectangle update_rect; - - /* Allocate a new pixmap with new height */ - GdkPixmap *pixmap = gdk_pixmap_new(drawing->drawing_area->window, - drawing->width + SAFETY, - drawing->height + height + SAFETY, - -1); - - /* Copy the high region */ - gdk_draw_drawable (pixmap, - drawing->drawing_area->style->black_gc, - drawing->pixmap, - 0, 0, - 0, 0, - drawing->width + SAFETY, y); - - - - - /* add an empty square */ - gdk_draw_rectangle (pixmap, - drawing->drawing_area->style->white_gc, - TRUE, - 0, y, - drawing->width + SAFETY, // do not overlap - height); - - - - /* copy the bottom of the region */ - gdk_draw_drawable (pixmap, - drawing->drawing_area->style->black_gc, - drawing->pixmap, - 0, y, - 0, y + height, - drawing->width+SAFETY, drawing->height - y + SAFETY); - - - - - if (drawing->pixmap) - gdk_pixmap_unref(drawing->pixmap); - - drawing->pixmap = pixmap; - - drawing->height+=height; - - /* Rectangle to update, from new drawing dimensions */ - //update_rect.x = 0 ; - //update_rect.y = y ; - //update_rect.width = drawing->width; - //update_rect.height = drawing->height - y ; - //gtk_widget_draw( drawing->drawing_area, &update_rect); -} - - -/* Remove a square corresponding to a removed process in the list */ -void drawing_remove_square(Drawing_t *drawing, - guint y, - guint height) -{ - //GdkRectangle update_rect; - - /* Allocate a new pixmap with new height */ - GdkPixmap *pixmap = gdk_pixmap_new( - drawing->drawing_area->window, - drawing->width + SAFETY, - drawing->height - height + SAFETY, - -1); - - /* Copy the high region */ - gdk_draw_drawable (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_drawable (pixmap, - drawing->drawing_area->style->black_gc, - drawing->pixmap, - 0, y + height, - 0, y, - drawing->width, drawing->height - y - height + SAFETY); - - - if (drawing->pixmap) - gdk_pixmap_unref(drawing->pixmap); - - drawing->pixmap = pixmap; - - drawing->height-=height; - - /* Rectangle to update, from new drawing dimensions */ - //update_rect.x = 0 ; - //update_rect.y = y ; - //update_rect.width = drawing->width; - //update_rect.height = drawing->height - y ; - //gtk_widget_draw( drawing->drawing_area, &update_rect); -} - - diff --git a/ltt/branches/poly/lttv/modules/guiControlFlow/Drawing.h b/ltt/branches/poly/lttv/modules/guiControlFlow/Drawing.h deleted file mode 100644 index d4b6afd6..00000000 --- a/ltt/branches/poly/lttv/modules/guiControlFlow/Drawing.h +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef _DRAWING_H -#define _DRAWING_H - -#include -#include -#include -#include -#include "CFV.h" -#include "Draw_Item.h" - - -#define SAFETY 50 // safety pixels at right and bottom of pixmap buffer - -/* 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. - */ - -typedef struct _Drawing_t Drawing_t; - -struct _Drawing_t { - GtkWidget *drawing_area; - GdkPixmap *pixmap; - ControlFlowData *control_flow_data; - - PangoLayout *pango_layout; - - gint height, width, depth; - -}; - -Drawing_t *drawing_construct(ControlFlowData *control_flow_data); -void drawing_destroy(Drawing_t *drawing); - -GtkWidget *drawing_get_widget(Drawing_t *drawing); - -//void drawing_Refresh ( Drawing_t *drawing, -// guint x, guint y, -// guint width, guint height); - -void drawing_draw_line( Drawing_t *drawing, - GdkPixmap *pixmap, - guint x1, guint y1, - guint x2, guint y2, - GdkGC *GC); - -//void drawing_copy( Drawing_t *drawing, -// guint xsrc, guint ysrc, -// guint xdest, guint ydest, -// guint width, guint height); - -/* Insert a square corresponding to a new process in the list */ -void drawing_insert_square(Drawing_t *drawing, - guint y, - guint height); - -/* Remove a square corresponding to a removed process in the list */ -void drawing_remove_square(Drawing_t *drawing, - guint y, - guint height); - - -//void drawing_Resize(Drawing_t *drawing, guint h, guint w); - -void convert_pixels_to_time( - gint width, - guint x, - LttTime *window_time_begin, - LttTime *window_time_end, - LttTime *time); - -void convert_time_to_pixels( - LttTime window_time_begin, - LttTime window_time_end, - LttTime time, - gint width, - guint *x); - -#endif // _DRAWING_H diff --git a/ltt/branches/poly/lttv/modules/guiControlFlow/Event_Hooks.c b/ltt/branches/poly/lttv/modules/guiControlFlow/Event_Hooks.c deleted file mode 100644 index 2905f6bd..00000000 --- a/ltt/branches/poly/lttv/modules/guiControlFlow/Event_Hooks.c +++ /dev/null @@ -1,1205 +0,0 @@ -/***************************************************************************** - * Hooks to be called by the main window * - *****************************************************************************/ - - -#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) - -//#define PANGO_ENABLE_BACKEND -#include -#include -#include -#include -#include - -//#include - -#include -#include -#include - -#include -#include -#include -#include - - -#include "Event_Hooks.h" -#include "CFV.h" -#include "Process_List.h" -#include "Drawing.h" -#include "CFV-private.h" - - -#define MAX_PATH_LEN 256 - - -/** - * Event Viewer's constructor hook - * - * This constructor is given as a parameter to the menuitem and toolbar button - * registration. It creates the list. - * @param mw A pointer to the parent window. - * @return The widget created. - */ -GtkWidget * -h_guicontrolflow(MainWindow *mw, LttvTracesetSelector * s, char * key) -{ - g_info("h_guicontrolflow, %p, %p, %s", mw, s, key); - ControlFlowData *control_flow_data = guicontrolflow() ; - - control_flow_data->mw = mw; - TimeWindow *time_window = guicontrolflow_get_time_window(control_flow_data); - time_window->start_time.tv_sec = 0; - time_window->start_time.tv_nsec = 0; - time_window->time_width.tv_sec = 0; - time_window->time_width.tv_nsec = 0; - - LttTime *current_time = guicontrolflow_get_current_time(control_flow_data); - current_time->tv_sec = 0; - current_time->tv_nsec = 0; - - //g_critical("time width1 : %u",time_window->time_width); - - get_time_window(mw, - time_window); - get_current_time(mw, - current_time); - - //g_critical("time width2 : %u",time_window->time_width); - // Unreg done in the GuiControlFlow_Destructor - reg_update_time_window(update_time_window_hook, control_flow_data, - mw); - reg_update_current_time(update_current_time_hook, control_flow_data, - mw); - return guicontrolflow_get_widget(control_flow_data) ; - -} - -int event_selected_hook(void *hook_data, void *call_data) -{ - ControlFlowData *control_flow_data = (ControlFlowData*) hook_data; - guint *event_number = (guint*) call_data; - - g_critical("DEBUG : event selected by main window : %u", *event_number); - -// control_flow_data->currently_Selected_Event = *event_number; -// control_flow_data->Selected_Event = TRUE ; - -// tree_v_set_cursor(control_flow_data); - -} - -/* Hook called before drawing. Gets the initial context at the beginning of the - * drawing interval and copy it to the context in event_request. - */ -int draw_before_hook(void *hook_data, void *call_data) -{ - EventRequest *event_request = (EventRequest*)hook_data; - //EventsContext Events_Context = (EventsContext*)call_data; - - //event_request->Events_Context = Events_Context; - - return 0; -} - -/* - * 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. - * - * 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 draw_event_hook(void *hook_data, void *call_data) -{ - EventRequest *event_request = (EventRequest*)hook_data; - ControlFlowData *control_flow_data = event_request->control_flow_data; - - LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; - - LttvTracefileState *tfs = (LttvTracefileState *)call_data; - - - LttEvent *e; - e = tfc->e; - - if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e)),"schedchange") == 0) - { - g_critical("schedchange!"); - - /* Add process to process list (if not present) and get drawing "y" from - * process position */ - guint pid_out, pid_in; - LttvProcessState *process_out, *process_in; - LttTime birth; - guint y_in = 0, y_out = 0, height = 0, pl_height = 0; - - ProcessList *process_list = - guicontrolflow_get_process_list(event_request->control_flow_data); - - - LttField *f = ltt_event_field(e); - LttField *element; - element = ltt_field_member(f,0); - pid_out = ltt_event_get_long_unsigned(e,element); - element = ltt_field_member(f,1); - pid_in = ltt_event_get_long_unsigned(e,element); - g_critical("out : %u in : %u", pid_out, pid_in); - - - /* Find process pid_out in the list... */ - process_out = lttv_state_find_process(tfs, pid_out); - g_critical("out : %s",g_quark_to_string(process_out->state->s)); - - birth = process_out->creation_time; - gchar *name = strdup(g_quark_to_string(process_out->name)); - HashedProcessData *hashed_process_data_out = NULL; - - if(processlist_get_process_pixels(process_list, - pid_out, - &birth, - &y_out, - &height, - &hashed_process_data_out) == 1) - { - /* Process not present */ - processlist_add(process_list, - pid_out, - &birth, - name, - &pl_height, - &hashed_process_data_out); - processlist_get_process_pixels(process_list, - pid_out, - &birth, - &y_out, - &height, - &hashed_process_data_out); - drawing_insert_square( event_request->control_flow_data->drawing, y_out, height); - } - - g_free(name); - - /* Find process pid_in in the list... */ - process_in = lttv_state_find_process(tfs, pid_in); - g_critical("in : %s",g_quark_to_string(process_in->state->s)); - - birth = process_in->creation_time; - name = strdup(g_quark_to_string(process_in->name)); - HashedProcessData *hashed_process_data_in = NULL; - - if(processlist_get_process_pixels(process_list, - pid_in, - &birth, - &y_in, - &height, - &hashed_process_data_in) == 1) - { - /* Process not present */ - processlist_add(process_list, - pid_in, - &birth, - name, - &pl_height, - &hashed_process_data_in); - processlist_get_process_pixels(process_list, - pid_in, - &birth, - &y_in, - &height, - &hashed_process_data_in); - - drawing_insert_square( event_request->control_flow_data->drawing, y_in, height); - } - g_free(name); - - - /* Find pixels corresponding to time of the event. If the time does - * not fit in the window, show a warning, not supposed to happend. */ - guint x = 0; - guint width = control_flow_data->drawing->drawing_area->allocation.width; - - LttTime time = ltt_event_time(e); - - LttTime window_end = ltt_time_add(control_flow_data->time_window.time_width, - control_flow_data->time_window.start_time); - - - convert_time_to_pixels( - control_flow_data->time_window.start_time, - window_end, - time, - width, - &x); - - assert(x <= width); - - /* draw what represents the event for outgoing process. */ - - DrawContext *draw_context_out = hashed_process_data_out->draw_context; - draw_context_out->current->modify_over->x = x; - draw_context_out->current->modify_over->y = y_out; - draw_context_out->drawable = control_flow_data->drawing->pixmap; - draw_context_out->pango_layout = control_flow_data->drawing->pango_layout; - GtkWidget *widget = control_flow_data->drawing->drawing_area; - //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)]; - draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap); - gdk_gc_copy(draw_context_out->gc, widget->style->black_gc); - //draw_context_out->gc = widget->style->black_gc; - - //draw_arc((void*)&prop_arc, (void*)draw_context_out); - //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap); - - GdkColor colorfg_out = { 0, 0xffff, 0x0000, 0x0000 }; - GdkColor colorbg_out = { 0, 0xffff, 0xffff, 0xffff }; - PropertiesText prop_text_out; - prop_text_out.foreground = &colorfg_out; - prop_text_out.background = &colorbg_out; - prop_text_out.size = 10; - prop_text_out.position = OVER; - - /* Print status of the process : U, WF, WC, E, W, R */ - if(process_out->state->s == LTTV_STATE_UNNAMED) - prop_text_out.text = "U"; - else if(process_out->state->s == LTTV_STATE_WAIT_FORK) - prop_text_out.text = "WF"; - else if(process_out->state->s == LTTV_STATE_WAIT_CPU) - prop_text_out.text = "WC"; - else if(process_out->state->s == LTTV_STATE_EXIT) - prop_text_out.text = "E"; - else if(process_out->state->s == LTTV_STATE_WAIT) - prop_text_out.text = "W"; - else if(process_out->state->s == LTTV_STATE_RUN) - prop_text_out.text = "R"; - else - prop_text_out.text = "U"; - - draw_text((void*)&prop_text_out, (void*)draw_context_out); - gdk_gc_unref(draw_context_out->gc); - - /* Draw the line of the out process */ - if(draw_context_out->previous->middle->x == -1) - { - draw_context_out->previous->middle->x = event_request->x_begin; - g_critical("out middle x_beg : %u",event_request->x_begin); - } - - draw_context_out->current->middle->x = x; - draw_context_out->current->middle->y = y_out + height/2; - draw_context_out->previous->middle->y = y_out + height/2; - draw_context_out->drawable = control_flow_data->drawing->pixmap; - draw_context_out->pango_layout = control_flow_data->drawing->pango_layout; - //draw_context_out->gc = widget->style->black_gc; - draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap); - gdk_gc_copy(draw_context_out->gc, widget->style->black_gc); - - PropertiesLine prop_line_out; - prop_line_out.color = g_new(GdkColor,1); - prop_line_out.line_width = 4; - prop_line_out.style = GDK_LINE_SOLID; - prop_line_out.position = MIDDLE; - - /* color of line : status of the process */ - if(process_out->state->s == LTTV_STATE_UNNAMED) - { - prop_line_out.color->red = 0x0000; - prop_line_out.color->green = 0x0000; - prop_line_out.color->blue = 0x0000; - } - else if(process_out->state->s == LTTV_STATE_WAIT_FORK) - { - prop_line_out.color->red = 0x0fff; - prop_line_out.color->green = 0x0000; - prop_line_out.color->blue = 0x0fff; - } - else if(process_out->state->s == LTTV_STATE_WAIT_CPU) - { - prop_line_out.color->red = 0x0fff; - prop_line_out.color->green = 0x0fff; - prop_line_out.color->blue = 0x0000; - } - else if(process_out->state->s == LTTV_STATE_EXIT) - { - prop_line_out.color->red = 0xffff; - prop_line_out.color->green = 0x0000; - prop_line_out.color->blue = 0xffff; - } - else if(process_out->state->s == LTTV_STATE_WAIT) - { - prop_line_out.color->red = 0xffff; - prop_line_out.color->green = 0x0000; - prop_line_out.color->blue = 0x0000; - } - else if(process_out->state->s == LTTV_STATE_RUN) - { - prop_line_out.color->red = 0x0000; - prop_line_out.color->green = 0xffff; - prop_line_out.color->blue = 0x0000; - } - else - { - prop_line_out.color->red = 0x0000; - prop_line_out.color->green = 0x0000; - prop_line_out.color->blue = 0x0000; - } - - draw_line((void*)&prop_line_out, (void*)draw_context_out); - g_free(prop_line_out.color); - gdk_gc_unref(draw_context_out->gc); - /* Note : finishing line will have to be added when trace read over. */ - - /* Finally, update the drawing context of the pid_in. */ - - DrawContext *draw_context_in = hashed_process_data_in->draw_context; - draw_context_in->current->modify_over->x = x; - draw_context_in->current->modify_over->y = y_in; - draw_context_in->drawable = control_flow_data->drawing->pixmap; - draw_context_in->pango_layout = control_flow_data->drawing->pango_layout; - widget = control_flow_data->drawing->drawing_area; - //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)]; - //draw_context_in->gc = widget->style->black_gc; - draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap); - gdk_gc_copy(draw_context_in->gc, widget->style->black_gc); - - //draw_arc((void*)&prop_arc, (void*)draw_context_in); - //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap); - - GdkColor colorfg_in = { 0, 0x0000, 0xffff, 0x0000 }; - GdkColor colorbg_in = { 0, 0xffff, 0xffff, 0xffff }; - PropertiesText prop_text_in; - prop_text_in.foreground = &colorfg_in; - prop_text_in.background = &colorbg_in; - prop_text_in.size = 10; - prop_text_in.position = OVER; - - /* Print status of the process : U, WF, WC, E, W, R */ - if(process_in->state->s == LTTV_STATE_UNNAMED) - prop_text_in.text = "U"; - else if(process_in->state->s == LTTV_STATE_WAIT_FORK) - prop_text_in.text = "WF"; - else if(process_in->state->s == LTTV_STATE_WAIT_CPU) - prop_text_in.text = "WC"; - else if(process_in->state->s == LTTV_STATE_EXIT) - prop_text_in.text = "E"; - else if(process_in->state->s == LTTV_STATE_WAIT) - prop_text_in.text = "W"; - else if(process_in->state->s == LTTV_STATE_RUN) - prop_text_in.text = "R"; - else - prop_text_in.text = "U"; - - draw_text((void*)&prop_text_in, (void*)draw_context_in); - gdk_gc_unref(draw_context_in->gc); - - /* Draw the line of the in process */ - if(draw_context_in->previous->middle->x == -1) - { - draw_context_in->previous->middle->x = event_request->x_begin; - g_critical("in middle x_beg : %u",event_request->x_begin); - } - - draw_context_in->current->middle->x = x; - draw_context_in->previous->middle->y = y_in + height/2; - draw_context_in->current->middle->y = y_in + height/2; - draw_context_in->drawable = control_flow_data->drawing->pixmap; - draw_context_in->pango_layout = control_flow_data->drawing->pango_layout; - //draw_context_in->gc = widget->style->black_gc; - draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap); - gdk_gc_copy(draw_context_in->gc, widget->style->black_gc); - - PropertiesLine prop_line_in; - prop_line_in.color = g_new(GdkColor,1); - prop_line_in.line_width = 4; - prop_line_in.style = GDK_LINE_SOLID; - prop_line_in.position = MIDDLE; - - /* color of line : status of the process */ - if(process_in->state->s == LTTV_STATE_UNNAMED) - { - prop_line_in.color->red = 0x0000; - prop_line_in.color->green = 0x0000; - prop_line_in.color->blue = 0x0000; - } - else if(process_in->state->s == LTTV_STATE_WAIT_FORK) - { - prop_line_in.color->red = 0x0fff; - prop_line_in.color->green = 0x0000; - prop_line_in.color->blue = 0x0fff; - } - else if(process_in->state->s == LTTV_STATE_WAIT_CPU) - { - prop_line_in.color->red = 0x0fff; - prop_line_in.color->green = 0x0fff; - prop_line_in.color->blue = 0x0000; - } - else if(process_in->state->s == LTTV_STATE_EXIT) - { - prop_line_in.color->red = 0xffff; - prop_line_in.color->green = 0x0000; - prop_line_in.color->blue = 0xffff; - } - else if(process_in->state->s == LTTV_STATE_WAIT) - { - prop_line_in.color->red = 0xffff; - prop_line_in.color->green = 0x0000; - prop_line_in.color->blue = 0x0000; - } - else if(process_in->state->s == LTTV_STATE_RUN) - { - prop_line_in.color->red = 0x0000; - prop_line_in.color->green = 0xffff; - prop_line_in.color->blue = 0x0000; - } - else - { - prop_line_in.color->red = 0x0000; - prop_line_in.color->green = 0x0000; - prop_line_in.color->blue = 0x0000; - } - - draw_line((void*)&prop_line_in, (void*)draw_context_in); - g_free(prop_line_in.color); - gdk_gc_unref(draw_context_in->gc); - } - - return 0; - - /* Temp dump */ -#ifdef DONTSHOW - GString *string = g_string_new("");; - gboolean field_names = TRUE, state = TRUE; - - lttv_event_to_string(e, tfc->tf, string, TRUE, field_names, tfs); - g_string_append_printf(string,"\n"); - - if(state) { - g_string_append_printf(string, " %s", - g_quark_to_string(tfs->process->state->s)); - } - - g_info("%s",string->str); - - g_string_free(string, TRUE); - - /* End of text dump */ -#endif //DONTSHOW - -} - - -int draw_after_hook(void *hook_data, void *call_data) -{ - EventRequest *event_request = (EventRequest*)hook_data; - ControlFlowData *control_flow_data = event_request->control_flow_data; - - LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; - - LttvTracefileState *tfs = (LttvTracefileState *)call_data; - - - LttEvent *e; - e = tfc->e; - - if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e)),"schedchange") == 0) - { - g_critical("schedchange!"); - - /* Add process to process list (if not present) and get drawing "y" from - * process position */ - guint pid_out, pid_in; - LttvProcessState *process_out, *process_in; - LttTime birth; - guint y_in = 0, y_out = 0, height = 0, pl_height = 0; - - ProcessList *process_list = - guicontrolflow_get_process_list(event_request->control_flow_data); - - - LttField *f = ltt_event_field(e); - LttField *element; - element = ltt_field_member(f,0); - pid_out = ltt_event_get_long_unsigned(e,element); - element = ltt_field_member(f,1); - pid_in = ltt_event_get_long_unsigned(e,element); - g_critical("out : %u in : %u", pid_out, pid_in); - - - /* Find process pid_out in the list... */ - process_out = lttv_state_find_process(tfs, pid_out); - g_critical("out : %s",g_quark_to_string(process_out->state->s)); - - birth = process_out->creation_time; - gchar *name = strdup(g_quark_to_string(process_out->name)); - HashedProcessData *hashed_process_data_out = NULL; - - if(processlist_get_process_pixels(process_list, - pid_out, - &birth, - &y_out, - &height, - &hashed_process_data_out) == 1) - { - /* Process not present */ - processlist_add(process_list, - pid_out, - &birth, - name, - &pl_height, - &hashed_process_data_out); - processlist_get_process_pixels(process_list, - pid_out, - &birth, - &y_out, - &height, - &hashed_process_data_out); - drawing_insert_square( event_request->control_flow_data->drawing, y_out, height); - } - - g_free(name); - - /* Find process pid_in in the list... */ - process_in = lttv_state_find_process(tfs, pid_in); - g_critical("in : %s",g_quark_to_string(process_in->state->s)); - - birth = process_in->creation_time; - name = strdup(g_quark_to_string(process_in->name)); - HashedProcessData *hashed_process_data_in = NULL; - - if(processlist_get_process_pixels(process_list, - pid_in, - &birth, - &y_in, - &height, - &hashed_process_data_in) == 1) - { - /* Process not present */ - processlist_add(process_list, - pid_in, - &birth, - name, - &pl_height, - &hashed_process_data_in); - processlist_get_process_pixels(process_list, - pid_in, - &birth, - &y_in, - &height, - &hashed_process_data_in); - - drawing_insert_square( event_request->control_flow_data->drawing, y_in, height); - } - g_free(name); - - - /* Find pixels corresponding to time of the event. If the time does - * not fit in the window, show a warning, not supposed to happend. */ - //guint x = 0; - //guint width = control_flow_data->drawing->drawing_area->allocation.width; - - //LttTime time = ltt_event_time(e); - - //LttTime window_end = ltt_time_add(control_flow_data->time_window.time_width, - // control_flow_data->time_window.start_time); - - - //convert_time_to_pixels( - // control_flow_data->time_window.start_time, - // window_end, - // time, - // width, - // &x); - - //assert(x <= width); - - /* draw what represents the event for outgoing process. */ - - DrawContext *draw_context_out = hashed_process_data_out->draw_context; - //draw_context_out->current->modify_over->x = x; - draw_context_out->current->modify_over->y = y_out; - draw_context_out->drawable = control_flow_data->drawing->pixmap; - draw_context_out->pango_layout = control_flow_data->drawing->pango_layout; - GtkWidget *widget = control_flow_data->drawing->drawing_area; - //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)]; - draw_context_out->gc = widget->style->black_gc; - - //draw_arc((void*)&prop_arc, (void*)draw_context_out); - //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap); - - GdkColor colorfg_out = { 0, 0xffff, 0x0000, 0x0000 }; - GdkColor colorbg_out = { 0, 0xffff, 0xffff, 0xffff }; - PropertiesText prop_text_out; - prop_text_out.foreground = &colorfg_out; - prop_text_out.background = &colorbg_out; - prop_text_out.size = 10; - prop_text_out.position = OVER; - - /* Print status of the process : U, WF, WC, E, W, R */ - if(process_out->state->s == LTTV_STATE_UNNAMED) - prop_text_out.text = "U"; - else if(process_out->state->s == LTTV_STATE_WAIT_FORK) - prop_text_out.text = "WF"; - else if(process_out->state->s == LTTV_STATE_WAIT_CPU) - prop_text_out.text = "WC"; - else if(process_out->state->s == LTTV_STATE_EXIT) - prop_text_out.text = "E"; - else if(process_out->state->s == LTTV_STATE_WAIT) - prop_text_out.text = "W"; - else if(process_out->state->s == LTTV_STATE_RUN) - prop_text_out.text = "R"; - else - prop_text_out.text = "U"; - - draw_text((void*)&prop_text_out, (void*)draw_context_out); - - draw_context_out->current->middle->y = y_out+height/2; - draw_context_out->current->status = process_out->state->s; - - /* for pid_out : remove previous, Prev = current, new current (default) */ - g_free(draw_context_out->previous->modify_under); - g_free(draw_context_out->previous->modify_middle); - g_free(draw_context_out->previous->modify_over); - g_free(draw_context_out->previous->under); - g_free(draw_context_out->previous->middle); - g_free(draw_context_out->previous->over); - g_free(draw_context_out->previous); - - draw_context_out->previous = draw_context_out->current; - - draw_context_out->current = g_new(DrawInfo,1); - draw_context_out->current->over = g_new(ItemInfo,1); - draw_context_out->current->over->x = -1; - draw_context_out->current->over->y = -1; - draw_context_out->current->middle = g_new(ItemInfo,1); - draw_context_out->current->middle->x = -1; - draw_context_out->current->middle->y = -1; - draw_context_out->current->under = g_new(ItemInfo,1); - draw_context_out->current->under->x = -1; - draw_context_out->current->under->y = -1; - draw_context_out->current->modify_over = g_new(ItemInfo,1); - draw_context_out->current->modify_over->x = -1; - draw_context_out->current->modify_over->y = -1; - draw_context_out->current->modify_middle = g_new(ItemInfo,1); - draw_context_out->current->modify_middle->x = -1; - draw_context_out->current->modify_middle->y = -1; - draw_context_out->current->modify_under = g_new(ItemInfo,1); - draw_context_out->current->modify_under->x = -1; - draw_context_out->current->modify_under->y = -1; - draw_context_out->current->status = LTTV_STATE_UNNAMED; - - /* Finally, update the drawing context of the pid_in. */ - - DrawContext *draw_context_in = hashed_process_data_in->draw_context; - //draw_context_in->current->modify_over->x = x; - draw_context_in->current->modify_over->y = y_in; - draw_context_in->drawable = control_flow_data->drawing->pixmap; - draw_context_in->pango_layout = control_flow_data->drawing->pango_layout; - widget = control_flow_data->drawing->drawing_area; - //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)]; - draw_context_in->gc = widget->style->black_gc; - - //draw_arc((void*)&prop_arc, (void*)draw_context_in); - //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap); - - GdkColor colorfg_in = { 0, 0x0000, 0xffff, 0x0000 }; - GdkColor colorbg_in = { 0, 0xffff, 0xffff, 0xffff }; - PropertiesText prop_text_in; - prop_text_in.foreground = &colorfg_in; - prop_text_in.background = &colorbg_in; - prop_text_in.size = 10; - prop_text_in.position = OVER; - - /* Print status of the process : U, WF, WC, E, W, R */ - if(process_in->state->s == LTTV_STATE_UNNAMED) - prop_text_in.text = "U"; - else if(process_in->state->s == LTTV_STATE_WAIT_FORK) - prop_text_in.text = "WF"; - else if(process_in->state->s == LTTV_STATE_WAIT_CPU) - prop_text_in.text = "WC"; - else if(process_in->state->s == LTTV_STATE_EXIT) - prop_text_in.text = "E"; - else if(process_in->state->s == LTTV_STATE_WAIT) - prop_text_in.text = "W"; - else if(process_in->state->s == LTTV_STATE_RUN) - prop_text_in.text = "R"; - else - prop_text_in.text = "U"; - - draw_text((void*)&prop_text_in, (void*)draw_context_in); - - draw_context_in->current->middle->y = y_in+height/2; - draw_context_in->current->status = process_in->state->s; - - /* for pid_in : remove previous, Prev = current, new current (default) */ - g_free(draw_context_in->previous->modify_under); - g_free(draw_context_in->previous->modify_middle); - g_free(draw_context_in->previous->modify_over); - g_free(draw_context_in->previous->under); - g_free(draw_context_in->previous->middle); - g_free(draw_context_in->previous->over); - g_free(draw_context_in->previous); - - draw_context_in->previous = draw_context_in->current; - - draw_context_in->current = g_new(DrawInfo,1); - draw_context_in->current->over = g_new(ItemInfo,1); - draw_context_in->current->over->x = -1; - draw_context_in->current->over->y = -1; - draw_context_in->current->middle = g_new(ItemInfo,1); - draw_context_in->current->middle->x = -1; - draw_context_in->current->middle->y = -1; - draw_context_in->current->under = g_new(ItemInfo,1); - draw_context_in->current->under->x = -1; - draw_context_in->current->under->y = -1; - draw_context_in->current->modify_over = g_new(ItemInfo,1); - draw_context_in->current->modify_over->x = -1; - draw_context_in->current->modify_over->y = -1; - draw_context_in->current->modify_middle = g_new(ItemInfo,1); - draw_context_in->current->modify_middle->x = -1; - draw_context_in->current->modify_middle->y = -1; - draw_context_in->current->modify_under = g_new(ItemInfo,1); - draw_context_in->current->modify_under->x = -1; - draw_context_in->current->modify_under->y = -1; - draw_context_in->current->status = LTTV_STATE_UNNAMED; - - } - - return 0; -} - - - - -gint update_time_window_hook(void *hook_data, void *call_data) -{ - ControlFlowData *control_flow_data = (ControlFlowData*) hook_data; - TimeWindow *old_time_window = - guicontrolflow_get_time_window(control_flow_data); - TimeWindow *new_time_window = ((TimeWindow*)call_data); - - /* 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 : %u, %u to %u, %u", - old_time_window->start_time.tv_sec, - old_time_window->start_time.tv_nsec, - old_time_window->time_width.tv_sec, - old_time_window->time_width.tv_nsec); - - g_info("New time window HOOK : %u, %u to %u, %u", - new_time_window->start_time.tv_sec, - new_time_window->start_time.tv_nsec, - new_time_window->time_width.tv_sec, - new_time_window->time_width.tv_nsec); - - if( new_time_window->time_width.tv_sec == old_time_window->time_width.tv_sec - && new_time_window->time_width.tv_nsec == old_time_window->time_width.tv_nsec) - { - /* Same scale (scrolling) */ - g_info("scrolling"); - LttTime *ns = &new_time_window->start_time; - LttTime *os = &old_time_window->start_time; - LttTime old_end = ltt_time_add(old_time_window->start_time, - old_time_window->time_width); - LttTime new_end = ltt_time_add(new_time_window->start_time, - new_time_window->time_width); - //if(nsdrawing->drawing_area->allocation.width; - convert_time_to_pixels( - *os, - old_end, - *ns, - width, - &x); - - /* Copy old data to new location */ - gdk_draw_drawable (control_flow_data->drawing->pixmap, - control_flow_data->drawing->drawing_area->style->white_gc, - control_flow_data->drawing->pixmap, - x, 0, - 0, 0, - -1, -1); - - convert_time_to_pixels( - *ns, - new_end, - old_end, - width, - &x); - - *old_time_window = *new_time_window; - /* Clear the data request background, but not SAFETY */ - gdk_draw_rectangle (control_flow_data->drawing->pixmap, - control_flow_data->drawing->drawing_area->style->white_gc, - TRUE, - x+SAFETY, 0, - control_flow_data->drawing->width - x, // do not overlap - control_flow_data->drawing->height+SAFETY); - /* Get new data for the rest. */ - drawing_data_request(control_flow_data->drawing, - &control_flow_data->drawing->pixmap, - x, 0, - control_flow_data->drawing->width - x, - control_flow_data->drawing->height); - - drawing_refresh(control_flow_data->drawing, - 0, 0, - control_flow_data->drawing->width, - control_flow_data->drawing->height); - - - } else { - //if(nsdrawing->drawing_area->allocation.width; - convert_time_to_pixels( - *ns, - new_end, - *os, - width, - &x); - - /* Copy old data to new location */ - gdk_draw_drawable (control_flow_data->drawing->pixmap, - control_flow_data->drawing->drawing_area->style->white_gc, - control_flow_data->drawing->pixmap, - 0, 0, - x, 0, - -1, -1); - - *old_time_window = *new_time_window; - - /* Clean the data request background */ - gdk_draw_rectangle (control_flow_data->drawing->pixmap, - control_flow_data->drawing->drawing_area->style->white_gc, - TRUE, - 0, 0, - x, // do not overlap - control_flow_data->drawing->height+SAFETY); - /* Get new data for the rest. */ - drawing_data_request(control_flow_data->drawing, - &control_flow_data->drawing->pixmap, - 0, 0, - x, - control_flow_data->drawing->height); - - drawing_refresh(control_flow_data->drawing, - 0, 0, - control_flow_data->drawing->width, - control_flow_data->drawing->height); - - } else { - g_info("scrolling far"); - /* Cannot reuse any part of the screen : far jump */ - *old_time_window = *new_time_window; - - - gdk_draw_rectangle (control_flow_data->drawing->pixmap, - control_flow_data->drawing->drawing_area->style->white_gc, - TRUE, - 0, 0, - control_flow_data->drawing->width+SAFETY, // do not overlap - control_flow_data->drawing->height+SAFETY); - - drawing_data_request(control_flow_data->drawing, - &control_flow_data->drawing->pixmap, - 0, 0, - control_flow_data->drawing->width, - control_flow_data->drawing->height); - - drawing_refresh(control_flow_data->drawing, - 0, 0, - control_flow_data->drawing->width, - control_flow_data->drawing->height); - } - } - } else { - /* Different scale (zoom) */ - g_info("zoom"); - - *old_time_window = *new_time_window; - - gdk_draw_rectangle (control_flow_data->drawing->pixmap, - control_flow_data->drawing->drawing_area->style->white_gc, - TRUE, - 0, 0, - control_flow_data->drawing->width+SAFETY, // do not overlap - control_flow_data->drawing->height+SAFETY); - - - drawing_data_request(control_flow_data->drawing, - &control_flow_data->drawing->pixmap, - 0, 0, - control_flow_data->drawing->width, - control_flow_data->drawing->height); - - drawing_refresh(control_flow_data->drawing, - 0, 0, - control_flow_data->drawing->width, - control_flow_data->drawing->height); - } - - return 0; -} - -gint update_current_time_hook(void *hook_data, void *call_data) -{ - ControlFlowData *control_flow_data = (ControlFlowData*)hook_data; - - LttTime* current_time = - guicontrolflow_get_current_time(control_flow_data); - *current_time = *((LttTime*)call_data); - - TimeWindow time_window; - - LttTime time_begin = control_flow_data->time_window.start_time; - LttTime width = control_flow_data->time_window.time_width; - LttTime half_width = ltt_time_div(width,2.0); - LttTime time_end = ltt_time_add(time_begin, width); - - LttvTracesetContext * tsc = - get_traceset_context(control_flow_data->mw); - - LttTime trace_start = tsc->Time_Span->startTime; - LttTime trace_end = tsc->Time_Span->endTime; - - g_info("New current time HOOK : %u, %u", 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) == -1) - { - if(ltt_time_compare(*current_time, - ltt_time_add(trace_start,half_width)) == -1) - time_begin = trace_start; - else - time_begin = ltt_time_sub(*current_time,half_width); - - time_window.start_time = time_begin; - time_window.time_width = width; - - set_time_window(control_flow_data->mw, &time_window); - } - else if(ltt_time_compare(*current_time, time_end) == 1) - { - if(ltt_time_compare(*current_time, ltt_time_sub(trace_end, half_width)) == 1) - time_begin = ltt_time_sub(trace_end,width); - else - time_begin = ltt_time_sub(*current_time,half_width); - - time_window.start_time = time_begin; - time_window.time_width = width; - - set_time_window(control_flow_data->mw, &time_window); - - } - gtk_widget_queue_draw(control_flow_data->drawing->drawing_area); - - return 0; -} - -typedef struct _ClosureData { - EventRequest *event_request; - LttvTraceState *ts; -} ClosureData; - - -void draw_closure(gpointer key, gpointer value, gpointer user_data) -{ - ProcessInfo *process_info = (ProcessInfo*)key; - HashedProcessData *hashed_process_data = (HashedProcessData*)value; - ClosureData *closure_data = (ClosureData*)user_data; - - ControlFlowData *control_flow_data = - closure_data->event_request->control_flow_data; - - GtkWidget *widget = control_flow_data->drawing->drawing_area; - - /* Get y position of process */ - gint y=0, height=0; - - processlist_get_pixels_from_data( control_flow_data->process_list, - process_info, - hashed_process_data, - &y, - &height); - /* Get last state of process */ - LttvTraceContext *tc = - (LttvTraceContext *)closure_data->ts; - - LttvTraceState *ts = closure_data->ts; - LttvProcessState *process; - - process = lttv_state_find_process((LttvTracefileState*)ts, process_info->pid); - - /* Draw the closing line */ - DrawContext *draw_context = hashed_process_data->draw_context; - if(draw_context->previous->middle->x == -1) - { - draw_context->previous->middle->x = closure_data->event_request->x_begin; - g_critical("out middle x_beg : %u",closure_data->event_request->x_begin); - } - - draw_context->current->middle->x = closure_data->event_request->x_end; - draw_context->current->middle->y = y + height/2; - draw_context->previous->middle->y = y + height/2; - draw_context->drawable = control_flow_data->drawing->pixmap; - draw_context->pango_layout = control_flow_data->drawing->pango_layout; - //draw_context->gc = widget->style->black_gc; - draw_context->gc = gdk_gc_new(control_flow_data->drawing->pixmap); - gdk_gc_copy(draw_context->gc, widget->style->black_gc); - - PropertiesLine prop_line; - prop_line.color = g_new(GdkColor,1); - prop_line.line_width = 6; - prop_line.style = GDK_LINE_SOLID; - prop_line.position = MIDDLE; - - /* color of line : status of the process */ - if(process->state->s == LTTV_STATE_UNNAMED) - { - prop_line.color->red = 0x0000; - prop_line.color->green = 0x0000; - prop_line.color->blue = 0x0000; - } - else if(process->state->s == LTTV_STATE_WAIT_FORK) - { - prop_line.color->red = 0x0fff; - prop_line.color->green = 0x0000; - prop_line.color->blue = 0x0fff; - } - else if(process->state->s == LTTV_STATE_WAIT_CPU) - { - prop_line.color->red = 0x0fff; - prop_line.color->green = 0x0fff; - prop_line.color->blue = 0x0000; - } - else if(process->state->s == LTTV_STATE_EXIT) - { - prop_line.color->red = 0xffff; - prop_line.color->green = 0x0000; - prop_line.color->blue = 0xffff; - } - else if(process->state->s == LTTV_STATE_WAIT) - { - prop_line.color->red = 0xffff; - prop_line.color->green = 0x0000; - prop_line.color->blue = 0x0000; - } - else if(process->state->s == LTTV_STATE_RUN) - { - prop_line.color->red = 0x0000; - prop_line.color->green = 0xffff; - prop_line.color->blue = 0x0000; - } - else - { - prop_line.color->red = 0x0000; - prop_line.color->green = 0x0000; - prop_line.color->blue = 0x0000; - } - - draw_line((void*)&prop_line, (void*)draw_context); - g_free(prop_line.color); - gdk_gc_unref(draw_context->gc); - - /* Reset draw_context of the process for next request */ - - hashed_process_data->draw_context->drawable = NULL; - hashed_process_data->draw_context->gc = NULL; - hashed_process_data->draw_context->pango_layout = NULL; - hashed_process_data->draw_context->current->over->x = -1; - hashed_process_data->draw_context->current->over->y = -1; - hashed_process_data->draw_context->current->middle->x = -1; - hashed_process_data->draw_context->current->middle->y = -1; - hashed_process_data->draw_context->current->under->x = -1; - hashed_process_data->draw_context->current->under->y = -1; - hashed_process_data->draw_context->current->modify_over->x = -1; - hashed_process_data->draw_context->current->modify_over->y = -1; - hashed_process_data->draw_context->current->modify_middle->x = -1; - hashed_process_data->draw_context->current->modify_middle->y = -1; - hashed_process_data->draw_context->current->modify_under->x = -1; - hashed_process_data->draw_context->current->modify_under->y = -1; - hashed_process_data->draw_context->current->status = LTTV_STATE_UNNAMED; - hashed_process_data->draw_context->previous->over->x = -1; - hashed_process_data->draw_context->previous->over->y = -1; - hashed_process_data->draw_context->previous->middle->x = -1; - hashed_process_data->draw_context->previous->middle->y = -1; - hashed_process_data->draw_context->previous->under->x = -1; - hashed_process_data->draw_context->previous->under->y = -1; - hashed_process_data->draw_context->previous->modify_over->x = -1; - hashed_process_data->draw_context->previous->modify_over->y = -1; - hashed_process_data->draw_context->previous->modify_middle->x = -1; - hashed_process_data->draw_context->previous->modify_middle->y = -1; - hashed_process_data->draw_context->previous->modify_under->x = -1; - hashed_process_data->draw_context->previous->modify_under->y = -1; - hashed_process_data->draw_context->previous->status = LTTV_STATE_UNNAMED; - - -} - -/* - * for each process - * draw closing line - * new default prev and current - */ -int after_data_request(void *hook_data, void *call_data) -{ - EventRequest *event_request = (EventRequest*)hook_data; - ControlFlowData *control_flow_data = event_request->control_flow_data; - - ProcessList *process_list = - guicontrolflow_get_process_list(event_request->control_flow_data); - - ClosureData closure_data; - closure_data.event_request = (EventRequest*)hook_data; - closure_data.ts = (LttvTraceState*)call_data; - - g_hash_table_foreach(process_list->process_hash, draw_closure, - (void*)&closure_data); - -} - diff --git a/ltt/branches/poly/lttv/modules/guiControlFlow/Event_Hooks.h b/ltt/branches/poly/lttv/modules/guiControlFlow/Event_Hooks.h deleted file mode 100644 index 66170d3c..00000000 --- a/ltt/branches/poly/lttv/modules/guiControlFlow/Event_Hooks.h +++ /dev/null @@ -1,84 +0,0 @@ -/* Event_hooks.c 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 -#include -#include -#include "Process_List.h" -#include "Drawing.h" -#include "CFV.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(ProcessList *process_list, Drawing_t *drawing); - -GtkWidget *h_guicontrolflow(MainWindow *mw, LttvTracesetSelector * s, char * key); - -int event_selected_hook(void *hook_data, void *call_data); - -/* Hook called before drawing. Gets the initial context at the beginning of the - * drawing interval and copy it to the context in event_request. - */ -int draw_before_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. - * - * 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 draw_event_hook(void *hook_data, void *call_data); - -int draw_after_hook(void *hook_data, void *call_data); - -void draw_closure(gpointer key, gpointer value, gpointer user_data); - -int after_data_request(void *hook_data, void *call_data); - - -gint update_time_window_hook(void *hook_data, void *call_data); -gint update_current_time_hook(void *hook_data, void *call_data); - - - - -#endif // _EVENT_HOOKS_H diff --git a/ltt/branches/poly/lttv/modules/guiControlFlow/Makefile.am b/ltt/branches/poly/lttv/modules/guiControlFlow/Makefile.am deleted file mode 100644 index a8e1f7b7..00000000 --- a/ltt/branches/poly/lttv/modules/guiControlFlow/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -# -# Makefile for LTT New generation user interface : plugins. -# -# Created by Mathieu Desnoyers on September 27, 2003 -# - -AM_CFLAGS = $(GLIB_CFLAGS) -AM_CFLAGS += $(GTK_CFLAGS) -LIBS += $(GLIB_LIBS) -LIBS += $(GTK_LIBS) -L${top_srcdir}/lttv/modules/gui/API -lmainWinApi - -libdir = ${lttvplugindir} - -lib_LTLIBRARIES = libguiControlFlow.la -libguiControlFlow_la_LDFLAGS = -module -libguiControlFlow_la_SOURCES = module.c Event_Hooks.c CFV.c Process_List.c\ - Drawing.c Draw_Item.c - -noinst_HEADERS = Event_Hooks.h CFV.h Process_List.h\ - Drawing.h Draw_Item.h diff --git a/ltt/branches/poly/lttv/modules/guiControlFlow/Process_List.c b/ltt/branches/poly/lttv/modules/guiControlFlow/Process_List.c deleted file mode 100644 index c695fb15..00000000 --- a/ltt/branches/poly/lttv/modules/guiControlFlow/Process_List.c +++ /dev/null @@ -1,510 +0,0 @@ - -#include -#include -#include "Process_List.h" -#include "Draw_Item.h" - -/***************************************************************************** - * Methods to synchronize process list * - *****************************************************************************/ - -/* Enumeration of the columns */ -enum -{ - PROCESS_COLUMN, - PID_COLUMN, - BIRTH_S_COLUMN, - BIRTH_NS_COLUMN, - N_COLUMNS -}; - - -gint process_sort_func ( GtkTreeModel *model, - GtkTreeIter *it_a, - GtkTreeIter *it_b, - gpointer user_data) -{ - GValue a, b; - - memset(&a, 0, sizeof(GValue)); - memset(&b, 0, sizeof(GValue)); - - /* Order by PID */ - gtk_tree_model_get_value( model, - it_a, - PID_COLUMN, - &a); - - gtk_tree_model_get_value( model, - it_b, - PID_COLUMN, - &b); - - if(G_VALUE_TYPE(&a) == G_TYPE_UINT - && G_VALUE_TYPE(&b) == G_TYPE_UINT ) - { - if(g_value_get_uint(&a) > g_value_get_uint(&b)) - { - g_value_unset(&a); - g_value_unset(&b); - return 1; - } - if(g_value_get_uint(&a) < g_value_get_uint(&b)) - { - g_value_unset(&a); - g_value_unset(&b); - return 0; - } - } - - g_value_unset(&a); - g_value_unset(&b); - - - /* Order by birth second */ - gtk_tree_model_get_value( model, - it_a, - BIRTH_S_COLUMN, - &a); - - gtk_tree_model_get_value( model, - it_b, - BIRTH_S_COLUMN, - &b); - - - if(G_VALUE_TYPE(&a) == G_TYPE_ULONG - && G_VALUE_TYPE(&b) == G_TYPE_ULONG ) - { - if(g_value_get_ulong(&a) > g_value_get_ulong(&b)) - { - g_value_unset(&a); - g_value_unset(&b); - return 1; - } - if(g_value_get_ulong(&a) < g_value_get_ulong(&b)) - { - g_value_unset(&a); - g_value_unset(&b); - return 0; - } - - } - - g_value_unset(&a); - g_value_unset(&b); - - /* Order by birth nanosecond */ - gtk_tree_model_get_value( model, - it_a, - BIRTH_NS_COLUMN, - &a); - - gtk_tree_model_get_value( model, - it_b, - BIRTH_NS_COLUMN, - &b); - - - if(G_VALUE_TYPE(&a) == G_TYPE_ULONG - && G_VALUE_TYPE(&b) == G_TYPE_ULONG ) - { - if(g_value_get_ulong(&a) > g_value_get_ulong(&b)) - { - g_value_unset(&a); - g_value_unset(&b); - return 1; - } - // Final condition - //if(g_value_get_ulong(&a) < g_value_get_ulong(&b)) - //{ - // g_value_unset(&a); - // g_value_unset(&b); - // return 0; - //} - - } - - g_value_unset(&a); - g_value_unset(&b); - - return 0; - -} - -guint hash_fct(gconstpointer key) -{ - return ((ProcessInfo*)key)->pid; -} - -gboolean equ_fct(gconstpointer a, gconstpointer b) -{ - if(((ProcessInfo*)a)->pid != ((ProcessInfo*)b)->pid) - return 0; -// g_critical("compare %u and %u",((ProcessInfo*)a)->pid,((ProcessInfo*)b)->pid); - if(((ProcessInfo*)a)->birth.tv_sec != ((ProcessInfo*)b)->birth.tv_sec) - return 0; -// g_critical("compare %u and %u",((ProcessInfo*)a)->birth.tv_sec,((ProcessInfo*)b)->birth.tv_sec); - - if(((ProcessInfo*)a)->birth.tv_nsec != ((ProcessInfo*)b)->birth.tv_nsec) - return 0; -// g_critical("compare %u and %u",((ProcessInfo*)a)->birth.tv_nsec,((ProcessInfo*)b)->birth.tv_nsec); - - return 1; -} - -void destroy_hash_key(gpointer key); - -void destroy_hash_data(gpointer data); - - - - -ProcessList *processlist_construct(void) -{ - GtkTreeViewColumn *column; - GtkCellRenderer *renderer; - - ProcessList* process_list = g_new(ProcessList,1); - - process_list->number_of_process = 0; - - /* Create the Process list */ - process_list->list_store = gtk_list_store_new ( N_COLUMNS, - G_TYPE_STRING, - G_TYPE_UINT, - G_TYPE_ULONG, - G_TYPE_ULONG); - - - process_list->process_list_widget = - gtk_tree_view_new_with_model - (GTK_TREE_MODEL (process_list->list_store)); - - g_object_unref (G_OBJECT (process_list->list_store)); - - gtk_tree_sortable_set_sort_func( - GTK_TREE_SORTABLE(process_list->list_store), - PID_COLUMN, - process_sort_func, - NULL, - NULL); - - gtk_tree_sortable_set_sort_column_id( - GTK_TREE_SORTABLE(process_list->list_store), - PID_COLUMN, - GTK_SORT_ASCENDING); - - process_list->process_hash = g_hash_table_new_full( - hash_fct, equ_fct, - destroy_hash_key, destroy_hash_data - ); - - - gtk_tree_view_set_headers_visible( - GTK_TREE_VIEW(process_list->process_list_widget), FALSE); - - /* Create a column, associating the "text" attribute of the - * cell_renderer to the first column of the model */ - /* Columns alignment : 0.0 : Left 0.5 : Center 1.0 : Right */ - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ( "Process", - renderer, - "text", - PROCESS_COLUMN, - NULL); - gtk_tree_view_column_set_alignment (column, 0.0); - gtk_tree_view_column_set_fixed_width (column, 45); - gtk_tree_view_append_column ( - GTK_TREE_VIEW (process_list->process_list_widget), column); - - column = gtk_tree_view_column_new_with_attributes ( "PID", - renderer, - "text", - PID_COLUMN, - NULL); - gtk_tree_view_append_column ( - GTK_TREE_VIEW (process_list->process_list_widget), column); - - - column = gtk_tree_view_column_new_with_attributes ( "Birth sec", - renderer, - "text", - BIRTH_S_COLUMN, - NULL); - gtk_tree_view_append_column ( - GTK_TREE_VIEW (process_list->process_list_widget), column); - - //gtk_tree_view_column_set_visible(column, 0); - // - column = gtk_tree_view_column_new_with_attributes ( "Birth nsec", - renderer, - "text", - BIRTH_NS_COLUMN, - NULL); - gtk_tree_view_append_column ( - GTK_TREE_VIEW (process_list->process_list_widget), column); - - //gtk_tree_view_column_set_visible(column, 0); - - g_object_set_data_full( - G_OBJECT(process_list->process_list_widget), - "process_list_Data", - process_list, - (GDestroyNotify)processlist_destroy); - - return process_list; -} -void processlist_destroy(ProcessList *process_list) -{ - g_hash_table_destroy(process_list->process_hash); - process_list->process_hash = NULL; - - g_free(process_list); -} - -GtkWidget *processlist_get_widget(ProcessList *process_list) -{ - return process_list->process_list_widget; -} - - - -gint get_cell_height(GtkTreeView *tree_view) -{ - gint height; - GtkTreeViewColumn *Column = gtk_tree_view_get_column(tree_view, 0); - //GList *Render_List = gtk_tree_view_column_get_cell_renderers(Column); - //GtkCellRenderer *Renderer = g_list_first(Render_List)->data; - - //g_list_free(Render_List); - gtk_tree_view_column_cell_get_size(Column, NULL, NULL, NULL, NULL, &height); - //g_critical("cell 0 height : %u",height); - - return height; -} - -void destroy_hash_key(gpointer key) -{ - g_free(key); -} - -void destroy_hash_data(gpointer data) -{ - g_free(data); -} - -int processlist_add( ProcessList *process_list, - guint pid, - LttTime *birth, - gchar *name, - guint *height, - HashedProcessData **pm_hashed_process_data) -{ - GtkTreeIter iter ; - ProcessInfo *Process_Info = g_new(ProcessInfo, 1); - HashedProcessData *hashed_process_data = g_new(HashedProcessData, 1); - *pm_hashed_process_data = hashed_process_data; - - Process_Info->pid = pid; - Process_Info->birth = *birth; - - hashed_process_data->draw_context = g_new(DrawContext, 1); - hashed_process_data->draw_context->drawable = NULL; - hashed_process_data->draw_context->gc = NULL; - hashed_process_data->draw_context->pango_layout = NULL; - hashed_process_data->draw_context->current = g_new(DrawInfo,1); - hashed_process_data->draw_context->current->over = g_new(ItemInfo,1); - hashed_process_data->draw_context->current->over->x = -1; - hashed_process_data->draw_context->current->over->y = -1; - hashed_process_data->draw_context->current->middle = g_new(ItemInfo,1); - hashed_process_data->draw_context->current->middle->x = -1; - hashed_process_data->draw_context->current->middle->y = -1; - hashed_process_data->draw_context->current->under = g_new(ItemInfo,1); - hashed_process_data->draw_context->current->under->x = -1; - hashed_process_data->draw_context->current->under->y = -1; - hashed_process_data->draw_context->current->modify_over = g_new(ItemInfo,1); - hashed_process_data->draw_context->current->modify_over->x = -1; - hashed_process_data->draw_context->current->modify_over->y = -1; - hashed_process_data->draw_context->current->modify_middle = g_new(ItemInfo,1); - hashed_process_data->draw_context->current->modify_middle->x = -1; - hashed_process_data->draw_context->current->modify_middle->y = -1; - hashed_process_data->draw_context->current->modify_under = g_new(ItemInfo,1); - hashed_process_data->draw_context->current->modify_under->x = -1; - hashed_process_data->draw_context->current->modify_under->y = -1; - hashed_process_data->draw_context->current->status = LTTV_STATE_UNNAMED; - hashed_process_data->draw_context->previous = g_new(DrawInfo,1); - hashed_process_data->draw_context->previous->over = g_new(ItemInfo,1); - hashed_process_data->draw_context->previous->over->x = -1; - hashed_process_data->draw_context->previous->over->y = -1; - hashed_process_data->draw_context->previous->middle = g_new(ItemInfo,1); - hashed_process_data->draw_context->previous->middle->x = -1; - hashed_process_data->draw_context->previous->middle->y = -1; - hashed_process_data->draw_context->previous->under = g_new(ItemInfo,1); - hashed_process_data->draw_context->previous->under->x = -1; - hashed_process_data->draw_context->previous->under->y = -1; - hashed_process_data->draw_context->previous->modify_over = g_new(ItemInfo,1); - hashed_process_data->draw_context->previous->modify_over->x = -1; - hashed_process_data->draw_context->previous->modify_over->y = -1; - hashed_process_data->draw_context->previous->modify_middle = g_new(ItemInfo,1); - hashed_process_data->draw_context->previous->modify_middle->x = -1; - hashed_process_data->draw_context->previous->modify_middle->y = -1; - hashed_process_data->draw_context->previous->modify_under = g_new(ItemInfo,1); - hashed_process_data->draw_context->previous->modify_under->x = -1; - hashed_process_data->draw_context->previous->modify_under->y = -1; - hashed_process_data->draw_context->previous->status = LTTV_STATE_UNNAMED; - - /* Add a new row to the model */ - gtk_list_store_append ( process_list->list_store, &iter); - //g_critical ( "iter before : %s", gtk_tree_path_to_string ( - // gtk_tree_model_get_path ( - // GTK_TREE_MODEL(process_list->list_store), - // &iter))); - gtk_list_store_set ( process_list->list_store, &iter, - PROCESS_COLUMN, name, - PID_COLUMN, pid, - BIRTH_S_COLUMN, birth->tv_sec, - BIRTH_NS_COLUMN, birth->tv_nsec, - -1); - hashed_process_data->row_ref = gtk_tree_row_reference_new ( - GTK_TREE_MODEL(process_list->list_store), - gtk_tree_model_get_path( - GTK_TREE_MODEL(process_list->list_store), - &iter)); - g_hash_table_insert( process_list->process_hash, - (gpointer)Process_Info, - (gpointer)hashed_process_data); - - //g_critical ( "iter after : %s", gtk_tree_path_to_string ( - // gtk_tree_model_get_path ( - // GTK_TREE_MODEL(process_list->list_store), - // &iter))); - process_list->number_of_process++; - - *height = get_cell_height(GTK_TREE_VIEW(process_list->process_list_widget)) - * process_list->number_of_process ; - - - return 0; - -} - -int processlist_remove( ProcessList *process_list, - guint pid, - LttTime *birth) -{ - ProcessInfo Process_Info; - gint *path_indices; - HashedProcessData *hashed_process_data; - GtkTreeIter iter; - - Process_Info.pid = pid; - Process_Info.birth = *birth; - - - if(hashed_process_data = - (HashedProcessData*)g_hash_table_lookup( - process_list->process_hash, - &Process_Info)) - { - gtk_tree_model_get_iter ( - GTK_TREE_MODEL(process_list->list_store), - &iter, - gtk_tree_row_reference_get_path( - (GtkTreeRowReference*)hashed_process_data->row_ref) - ); - - gtk_list_store_remove (process_list->list_store, &iter); - - g_free(hashed_process_data->draw_context->previous->modify_under); - g_free(hashed_process_data->draw_context->previous->modify_middle); - g_free(hashed_process_data->draw_context->previous->modify_over); - g_free(hashed_process_data->draw_context->previous->under); - g_free(hashed_process_data->draw_context->previous->middle); - g_free(hashed_process_data->draw_context->previous->over); - g_free(hashed_process_data->draw_context->previous); - g_free(hashed_process_data->draw_context->current->modify_under); - g_free(hashed_process_data->draw_context->current->modify_middle); - g_free(hashed_process_data->draw_context->current->modify_over); - g_free(hashed_process_data->draw_context->current->under); - g_free(hashed_process_data->draw_context->current->middle); - g_free(hashed_process_data->draw_context->current->over); - g_free(hashed_process_data->draw_context->current); - g_free(hashed_process_data->draw_context); - g_free(hashed_process_data); - - g_hash_table_remove(process_list->process_hash, - &Process_Info); - - process_list->number_of_process--; - - return 0; - } else { - return 1; - } -} - - -guint processlist_get_height(ProcessList *process_list) -{ - return get_cell_height(GTK_TREE_VIEW(process_list->process_list_widget)) - * process_list->number_of_process ; -} - - -gint processlist_get_process_pixels( ProcessList *process_list, - guint pid, LttTime *birth, - guint *y, - guint *height, - HashedProcessData **pm_hashed_process_data) -{ - ProcessInfo Process_Info; - gint *path_indices; - GtkTreePath *tree_path; - HashedProcessData *hashed_process_data = NULL; - - Process_Info.pid = pid; - Process_Info.birth = *birth; - - if(hashed_process_data = - (HashedProcessData*)g_hash_table_lookup( - process_list->process_hash, - &Process_Info)) - { - tree_path = gtk_tree_row_reference_get_path( - hashed_process_data->row_ref); - path_indices = gtk_tree_path_get_indices (tree_path); - - *height = get_cell_height( - GTK_TREE_VIEW(process_list->process_list_widget)); - *y = *height * path_indices[0]; - *pm_hashed_process_data = hashed_process_data; - return 0; - } else { - *pm_hashed_process_data = hashed_process_data; - return 1; - } - -} - - -gint processlist_get_pixels_from_data( ProcessList *process_list, - ProcessInfo *process_info, - HashedProcessData *hashed_process_data, - guint *y, - guint *height) -{ - gint *path_indices; - GtkTreePath *tree_path; - - tree_path = gtk_tree_row_reference_get_path( - hashed_process_data->row_ref); - path_indices = gtk_tree_path_get_indices (tree_path); - - *height = get_cell_height( - GTK_TREE_VIEW(process_list->process_list_widget)); - *y = *height * path_indices[0]; - - return 0; - -} diff --git a/ltt/branches/poly/lttv/modules/guiControlFlow/Process_List.h b/ltt/branches/poly/lttv/modules/guiControlFlow/Process_List.h deleted file mode 100644 index d3272160..00000000 --- a/ltt/branches/poly/lttv/modules/guiControlFlow/Process_List.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef _PROCESS_LIST_H -#define _PROCESS_LIST_H - -#include -#include -#include -#include "Draw_Item.h" - -/* The process list - * - * Tasks : - * Create a process list - * contains the data for the process list - * tells the height of the process list widget - * provides methods to add/remove process from the list - * note : the sync with drawing is left to the caller. - * provides helper function to convert a process unique identifier to - * pixels (in height). - * - * //FIXME : connect the scrolled window adjustment with the list. - */ - -typedef struct _ProcessInfo { - - guint pid; - LttTime birth; - -} ProcessInfo; - -typedef struct _HashedProcessData { - - GtkTreeRowReference *row_ref; - DrawContext *draw_context; - -} HashedProcessData; - -struct _ProcessList { - - GtkWidget *process_list_widget; - GtkListStore *list_store; - - /* A hash table by PID to speed up process position find in the list */ - GHashTable *process_hash; - - guint number_of_process; -}; - - -typedef struct _ProcessList ProcessList; - -ProcessList *processlist_construct(void); -void processlist_destroy(ProcessList *process_list); -GtkWidget *processlist_get_widget(ProcessList *process_list); - -// out : success (0) and height -int processlist_add(ProcessList *process_list, guint pid, LttTime *birth, - gchar *name, guint *height, HashedProcessData **hashed_process_data); -// out : success (0) and height -int processlist_remove(ProcessList *process_list, guint pid, LttTime *birth); - -guint processlist_get_height(ProcessList *process_list); - -// Returns 0 on success -gint processlist_get_process_pixels(ProcessList *process_list, - guint pid, LttTime *birth, - guint *y, guint *height, - HashedProcessData **hashed_process_data); - -gint processlist_get_pixels_from_data( ProcessList *process_list, - ProcessInfo *process_info, - HashedProcessData *hashed_process_data, - guint *y, - guint *height); - -#endif // _PROCESS_LIST_H diff --git a/ltt/branches/poly/lttv/modules/guiControlFlow/Widget_Callbacks.c.old b/ltt/branches/poly/lttv/modules/guiControlFlow/Widget_Callbacks.c.old deleted file mode 100644 index 873db1c6..00000000 --- a/ltt/branches/poly/lttv/modules/guiControlFlow/Widget_Callbacks.c.old +++ /dev/null @@ -1,51 +0,0 @@ -/***************************************************************************** - * Callbacks used for the viewer * - *****************************************************************************/ -void expose_event_cb (GtkWidget *widget, GdkEventExpose *expose, gpointer data) -{ - ControlFlowData *control_flow_data = (ControlFlowData*)data; - - EventRequest *event_request = g_new(sizeof(EventRequest)); - - event_request->control_flow_data = control_flow_data; - - /* Calculate, from pixels in expose, the time interval to get data */ - - get_time_from_pixels(expose->area.x, expose->area.width, - control_flow_data->drawing_Area_Info.width, - &control_flow_data->Begin_Time, &control_flow_data->End_Time, - &event_request->time_begin, &event_request->time_end) - - /* Look in statistics of the trace the processes present during the - * whole time interval _shown on the screen_. Modify the list of - * processes to match it. NOTE : modify, not recreate. If recreation is - * needed,keep a pointer to the currently selected event in the list. - */ - - /* Call the reading API to have events sent to drawing hooks */ - lttv_trace_set_process( control_flow_data->Trace_Set, - Draw_Before_Hooks, - Draw_Event_Hooks, - Draw_After_Hooks, - NULL, //FIXME : filter here - event_request->time_begin, - event_request->time_end); - -} - - -void v_scroll_cb (GtkAdjustment *adjustment, gpointer data) -{ - ControlFlowData *control_flow_data = (ControlFlowData*)data; - GtkTreePath *Tree_Path; - - g_critical("DEBUG : scroll signal, value : %f", adjustment->value); - - //get_test_data((int)adjustment->value, control_flow_data->Num_Visible_Events, - // control_flow_data); - - - -} - - diff --git a/ltt/branches/poly/lttv/modules/guiControlFlow/guiControlFlow.c.old b/ltt/branches/poly/lttv/modules/guiControlFlow/guiControlFlow.c.old deleted file mode 100644 index 5c7961d5..00000000 --- a/ltt/branches/poly/lttv/modules/guiControlFlow/guiControlFlow.c.old +++ /dev/null @@ -1,99 +0,0 @@ -//FIXME by including ltt.h -#include -typedef time_t ltt_time; - -typedef struct _ltt_time_interval -{ - ltt_time time_begin, time_end; -} ltt_time_interval; - -// ??? - - - /* Setup the hooks */ - Draw_Before_Hooks = lttv_hooks_new(); - Draw_Event_Hooks = lttv_hooks_new(); - Draw_After_Hooks = lttv_hooks_new(); - - lttv_hooks_add(Draw_Before_Hooks, Draw_Before_Hook, NULL); - lttv_hooks_add(Draw_Event_Hooks, Draw_Event_Hook, NULL); - lttv_hooks_add(Draw_After_Hooks, Draw_After_Hook, NULL); - - /* Destroy the hooks */ - - lttv_hooks_destroy(Draw_Before_Hooks); - lttv_hooks_destroy(Draw_Event_Hooks); - lttv_hooks_destroy(Draw_After_Hooks); - - - - -/***************************************************************************** - * Definition of structures * - *****************************************************************************/ - -/* 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; - ltt_time time_begin, time_end; - /* Fill the Events_Context during the initial expose, before calling for - * events. - */ - GArray Events_Context; //FIXME -} EventRequest ; - - - -/***************************************************************************** - * Function prototypes * - *****************************************************************************/ -//! Control Flow Viewer's constructor hook -GtkWidget *hGuiControlFlow(GtkWidget *mw); -//! Control Flow Viewer's constructor -ControlFlowData *GuiControlFlow(void); -//! Control Flow Viewer's destructor -void GuiControlFlow_Destructor(ControlFlowData *control_flow_data); - - -static int Event_Selected_Hook(void *hook_data, void *call_data); - -static lttv_hooks - *Draw_Before_Hooks, - *Draw_Event_Hooks, - *Draw_After_Hooks; - -Draw_Before_Hook(void *hook_data, void *call_data) -Draw_Event_Hook(void *hook_data, void *call_data) -Draw_After_Hook(void *hook_data, void *call_data) - - -//void Tree_V_set_cursor(ControlFlowData *control_flow_data); -//void Tree_V_get_cursor(ControlFlowData *control_flow_data); - -/* Prototype for selection handler callback */ -//static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data); -static void v_scroll_cb (GtkAdjustment *adjustment, gpointer data); -//static void Tree_V_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer data); -//static void Tree_V_size_request_cb (GtkWidget *widget, GtkRequisition *requisition, gpointer data); -//static void Tree_V_cursor_changed_cb (GtkWidget *widget, gpointer data); -//static void Tree_V_move_cursor_cb (GtkWidget *widget, GtkMovementStep arg1, gint arg2, gpointer data); - -static void expose_event_cb (GtkWidget *widget, GdkEventExpose *expose, gpointer data); - -void add_test_process(ControlFlowData *control_flow_data); - -static void get_test_data(guint event_number, guint List_Height, - ControlFlowData *control_flow_data); - -void add_test_data(ControlFlowData *control_flow_data); -void test_draw(ControlFlowData *control_flow_data); - -void drawing_Area_Init(ControlFlowData *control_flow_data); - - -/*\@}*/ diff --git a/ltt/branches/poly/lttv/modules/guiControlFlow/module.c b/ltt/branches/poly/lttv/modules/guiControlFlow/module.c deleted file mode 100644 index 216688fb..00000000 --- a/ltt/branches/poly/lttv/modules/guiControlFlow/module.c +++ /dev/null @@ -1,100 +0,0 @@ -/*! \defgroup guiEvents libguiControlFlow: The GUI ControlFlow display plugin */ -/*\@{*/ - -/*! \file guiControlFlow.c - * \brief Graphical plugin for showing control flow of a trace. - * - * This plugin adds a Control Flow Viewer functionnality to Linux TraceToolkit - * GUI when this plugin is loaded. The init and destroy functions add the - * viewer's insertion menu item and toolbar icon by calling gtkTraceSet's - * API functions. Then, when a viewer's object is created, the constructor - * creates ans register through API functions what is needed to interact - * with the TraceSet window. - * - * This plugin uses the gdk library to draw the events and gtk to interact - * with the user. - * - * Author : Mathieu Desnoyers, June 2003 - */ - -#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) - -#include -#include -#include -#include - -#include "CFV.h" -#include "Event_Hooks.h" - - #include "../icons/hGuiControlFlowInsert.xpm" - -static LttvModule *Main_Win_Module; - - -/** Array containing instanced objects. Used when module is unloaded */ -GSList *g_control_flow_data_list = NULL ; - - - - -/***************************************************************************** - * Functions for module loading/unloading * - *****************************************************************************/ -/** - * plugin's init function - * - * This function initializes the Control Flow Viewer functionnality through the - * gtkTraceSet API. - */ -G_MODULE_EXPORT void init(LttvModule *self, int argc, char *argv[]) { - - Main_Win_Module = lttv_module_require(self, "mainwin", argc, argv); - - if(Main_Win_Module == NULL) - { - g_critical("Can't load Control Flow Viewer : missing mainwin\n"); - return; - } - - g_info("GUI ControlFlow Viewer init()"); - - /* Register the toolbar insert button */ - toolbar_item_reg(hGuiControlFlowInsert_xpm, "Insert Control Flow Viewer", - h_guicontrolflow); - - /* Register the menu item insert entry */ - menu_item_reg("/", "Insert Control Flow Viewer", h_guicontrolflow); - -} - -void destroy_walk(gpointer data, gpointer user_data) -{ - g_info("Walk destroy GUI Control Flow Viewer"); - guicontrolflow_destructor_full((ControlFlowData*)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. - */ -G_MODULE_EXPORT void destroy() { - g_info("GUI Control Flow Viewer destroy()"); - int i; - - g_slist_foreach(g_control_flow_data_list, destroy_walk, NULL ); - - g_slist_free(g_control_flow_data_list); - - /* Unregister the toolbar insert button */ - toolbar_item_unreg(h_guicontrolflow); - - /* Unregister the menu item insert entry */ - menu_item_unreg(h_guicontrolflow); - -} diff --git a/ltt/branches/poly/lttv/modules/guiControlFlow/test.c b/ltt/branches/poly/lttv/modules/guiControlFlow/test.c deleted file mode 100644 index c326fc5f..00000000 --- a/ltt/branches/poly/lttv/modules/guiControlFlow/test.c +++ /dev/null @@ -1,558 +0,0 @@ - - -static void destroy_cb( GtkWidget *widget, - gpointer data ) -{ - gtk_main_quit (); -} - - - -int main(int argc, char **argv) -{ - GtkWidget *Window; - GtkWidget *CF_Viewer; - GtkWidget *VBox_V; - GtkWidget *HScroll_VC; - ControlFlowData *control_flow_data; - guint ev_sel = 444 ; - /* Horizontal scrollbar and it's adjustment */ - GtkWidget *VScroll_VC; - GtkAdjustment *v_adjust ; - - /* Initialize i18n support */ - gtk_set_locale (); - - /* Initialize the widget set */ - gtk_init (&argc, &argv); - - init(); - - Window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title (GTK_WINDOW (Window), ("Test Window")); - - g_signal_connect (G_OBJECT (Window), "destroy", - G_CALLBACK (destroy_cb), NULL); - - - VBox_V = gtk_vbox_new(0, 0); - gtk_container_add (GTK_CONTAINER (Window), VBox_V); - - //ListViewer = hGuiEvents(Window); - //gtk_box_pack_start(GTK_BOX(VBox_V), ListViewer, TRUE, TRUE, 0); - - //ListViewer = hGuiEvents(Window); - //gtk_box_pack_start(GTK_BOX(VBox_V), ListViewer, FALSE, TRUE, 0); - - control_flow_data = guicontrolflow(); - CF_Viewer = control_flow_data->scrolled_window; - gtk_box_pack_start(GTK_BOX(VBox_V), CF_Viewer, TRUE, TRUE, 0); - - /* Create horizontal scrollbar and pack it */ - HScroll_VC = gtk_hscrollbar_new(NULL); - gtk_box_pack_start(GTK_BOX(VBox_V), HScroll_VC, FALSE, TRUE, 0); - - - gtk_widget_show (HScroll_VC); - gtk_widget_show (VBox_V); - gtk_widget_show (Window); - - //Event_Selected_Hook(control_flow_data, &ev_sel); - - gtk_main (); - - g_critical("main loop finished"); - - //h_guievents_destructor(ListViewer); - - //g_critical("GuiEvents Destructor finished"); - destroy(); - - return 0; -} - - - -void add_test_process(ControlFlowData *control_flow_data) -{ - GtkTreeIter iter; - int i; - gchar *process[] = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" }; - - for(i=0; inumber_of_process; i++) - { - /* Add a new row to the model */ - gtk_list_store_append (control_flow_data->list_store, &iter); - gtk_list_store_set ( control_flow_data->list_store, &iter, - PROCESS_COLUMN, process[i], - -1); - } - -} - - - - - - -void test_draw(ControlFlowData *control_flow_data) -{ - /* Draw event states using available height, Number of process, cell height - * (don't forget to remove two pixels at beginning and end). - * For horizontal : use width, Time_Begin, Time_End. - * This function calls the reading library to get the draw_hook called - * for the desired period of time. */ - - drawingAreaInfo *drawing_Area_Info = &control_flow_data->drawing_Area_Info; - - -} - -#ifdef DEBUG -void test_draw() { - gint cell_height = get_cell_height(GTK_TREE_VIEW(control_flow_data->process_list_widget)); - GdkGC *GC = gdk_gc_new(widget->window); - GdkColor color = CF_Colors[GREEN]; - - gdk_color_alloc (gdk_colormap_get_system () , &color); - - g_critical("expose"); - - /* When redrawing, use widget->allocation.width to get the width of - * drawable area. */ - control_flow_data->drawing_Area_Info.width = widget->allocation.width; - - test_draw(control_flow_data); - - gdk_gc_copy(GC,widget->style->white_gc); - gdk_gc_set_foreground(GC,&color); - - //gdk_draw_arc (widget->window, - // widget->style->fg_gc[GTK_WIDGET_STATE (widget)], - // TRUE, - // //0, 0, widget->allocation.width, widget->allocation.height, - // 0, 0, widget->allocation.width, - // control_flow_data->drawing_Area_Info.height, - // 0, 64 * 360); - - - //drawing_Area_Init(control_flow_data); - - // 2 pixels for the box around the drawing area, 1 pixel for off-by-one - // (starting from 0) - //gdk_gc_copy (&GC, widget->style->fg_gc[GTK_WIDGET_STATE (widget)]); - - gdk_gc_set_line_attributes(GC,12, GDK_LINE_SOLID, GDK_CAP_NOT_LAST,GDK_JOIN_MITER); - - gdk_draw_line (widget->window, - GC, - 0, (cell_height-1)/2, - widget->allocation.width, (cell_height-1)/2); - - color = CF_Colors[BLUE]; - - gdk_color_alloc (gdk_colormap_get_system () , &color); - - gdk_gc_set_foreground(GC,&color); - - - gdk_gc_set_line_attributes(GC,3, GDK_LINE_SOLID, GDK_CAP_NOT_LAST,GDK_JOIN_MITER); - - gdk_draw_line (widget->window, - GC, - 0, (cell_height-1)/2, - widget->allocation.width,(cell_height-1)/2); - - - - - - - g_object_unref(GC); - - //gdk_colormap_alloc_colors(gdk_colormap_get_system(), TRUE, - - //gdk_gc_set_line_attributes(GC,5, GDK_LINE_SOLID, GDK_CAP_NOT_LAST,GDK_JOIN_MITER); - //gdk_gc_set_foreground(GC, - - //gdk_draw_line (widget->window, - // GC, - // 0, (2*cell_height)-2-1, - // 50, (2*cell_height)-2-1); - -} -#endif //DEBUG - - -/* Event_Hook.c tests */ - -void test_draw_item(Drawing_t *drawing, - GdkPixmap *pixmap) -{ - PropertiesIcon properties_icon; - DrawContext draw_context; - - DrawInfo current, previous; - ItemInfo over, middle, under, modify_over, modify_middle, modify_under; - - int i=0,j=0; - - //for(i=0; i<1024;i=i+15) - { - // for(j=0;j<768;j=j+15) - { - over.x = i; - over.y = j; - - current.modify_over = &over; - - draw_context.drawable = pixmap; - draw_context.gc = drawing->drawing_area->style->black_gc; - - draw_context.current = ¤t; - draw_context.previous = NULL; - - properties_icon.icon_name = g_new(char, MAX_PATH_LEN); - strncpy(properties_icon.icon_name, - "/home/compudj/local/share/LinuxTraceToolkit/pixmaps/mini-display.xpm", - MAX_PATH_LEN); - properties_icon.width = -1; - properties_icon.height = -1; - properties_icon.position = OVER; - draw_icon(&properties_icon, &draw_context); - g_free(properties_icon.icon_name); - } - } - -} - -#ifdef NOTUSE -/* NOTE : no drawing data should be sent there, since the drawing widget - * has not been initialized */ -void send_test_drawing(ProcessList *process_list, - Drawing_t *drawing, - GdkPixmap *pixmap, - gint x, gint y, // y not used here? - gint width, - gint height) // height won't be used here ? -{ - int i,j; - ProcessInfo Process_Info = {10000, 12000, 55600}; - //ProcessInfo Process_Info = {156, 14000, 55500}; - GtkTreeRowReference *row_ref; - PangoContext *context; - PangoLayout *layout; - PangoFontDescription *FontDesc;// = pango_font_description_new(); - gint Font_Size; - - //icon - //GdkBitmap *mask = g_new(GdkBitmap, 1); - //GdkPixmap *icon_pixmap = g_new(GdkPixmap, 1); - GdkGC * gc; - // rectangle - GdkColor color = { 0, 0xffff, 0x0000, 0x0000 }; - - gc = gdk_gc_new(pixmap); - /* Sent text data */ - layout = gtk_widget_create_pango_layout(drawing->drawing_area, - NULL); - context = pango_layout_get_context(layout); - FontDesc = pango_context_get_font_description(context); - Font_Size = pango_font_description_get_size(FontDesc); - pango_font_description_set_size(FontDesc, Font_Size-3*PANGO_SCALE); - - - - - LttTime birth; - birth.tv_sec = 12000; - birth.tv_nsec = 55500; - g_info("we have : x : %u, y : %u, width : %u, height : %u", x, y, width, height); - processlist_get_process_pixels(process_list, - 1, - &birth, - &y, - &height); - - g_info("we draw : x : %u, y : %u, width : %u, height : %u", x, y, width, height); - drawing_draw_line( - drawing, pixmap, x, - y+(height/2), x + width, y+(height/2), - drawing->drawing_area->style->black_gc); - - pango_layout_set_text(layout, "Test", -1); - gdk_draw_layout(pixmap, drawing->drawing_area->style->black_gc, - 0, y+height, layout); - - birth.tv_sec = 14000; - birth.tv_nsec = 55500; - - processlist_get_process_pixels(process_list, - 156, - &birth, - &y, - &height); - - - drawing_draw_line( - drawing, pixmap, x, - y+(height/2), x + width, y+(height/2), - drawing->drawing_area->style->black_gc); - - g_info("y : %u, height : %u", y, height); - - - - birth.tv_sec = 12000; - birth.tv_nsec = 55700; - - processlist_get_process_pixels(process_list, - 10, - &birth, - &y, - &height); - - /* Draw rectangle (background color) */ - gdk_gc_copy(gc, drawing->drawing_area->style->black_gc); - gdk_gc_set_rgb_fg_color(gc, &color); - gdk_draw_rectangle(pixmap, gc, - TRUE, - x, y, width, height); - - drawing_draw_line( - drawing, pixmap, x, - y+(height/2), x + width, y+(height/2), - drawing->drawing_area->style->black_gc); - - - /* Draw arc */ - gdk_draw_arc(pixmap, drawing->drawing_area->style->black_gc, - TRUE, 100, y, height/2, height/2, 0, 360*64); - - g_info("y : %u, height : %u", y, height); - - for(i=0; i<10; i++) - { - birth.tv_sec = i*12000; - birth.tv_nsec = i*55700; - - processlist_get_process_pixels(process_list, - i, - &birth, - &y, - &height); - - - drawing_draw_line( - drawing, pixmap, x, - y+(height/2), x + width, y+(height/2), - drawing->drawing_area->style->black_gc); - - g_critical("y : %u, height : %u", y, height); - - } - - birth.tv_sec = 12000; - birth.tv_nsec = 55600; - - processlist_get_process_pixels(process_list, - 10, - &birth, - &y, - &height); - - - drawing_draw_line( - drawing, pixmap, x, - y+(height/2), x + width, y+(height/2), - drawing->drawing_area->style->black_gc); - - g_info("y : %u, height : %u", y, height); - - - /* IMPORTANT : This action uses the cpu heavily! */ - //icon_pixmap = gdk_pixmap_create_from_xpm(pixmap, &mask, NULL, -// "/home/compudj/local/share/LinuxTraceToolkit/pixmaps/move_message.xpm"); - // "/home/compudj/local/share/LinuxTraceToolkit/pixmaps/mini-display.xpm"); - - // gdk_gc_set_clip_mask(drawing->drawing_area->style->black_gc, mask); - -// for(i=x;idrawing_area->style->black_gc); -// gdk_gc_set_clip_origin(drawing->drawing_area->style->black_gc, i, j); -// gdk_draw_drawable(pixmap, -// drawing->drawing_area->style->black_gc, -// icon_pixmap, -// 0, 0, i, j, -1, -1); - -// } -// } - - test_draw_item(drawing,pixmap); - - //gdk_gc_set_clip_origin(drawing->drawing_area->style->black_gc, 0, 0); - //gdk_gc_set_clip_mask(drawing->drawing_area->style->black_gc, NULL); - - //g_free(icon_pixmap); - //g_free(mask); - - - - - - - pango_font_description_set_size(FontDesc, Font_Size); - g_object_unref(layout); - g_free(gc); -} - -void send_test_process(ProcessList *process_list, Drawing_t *drawing) -{ - guint height, y; - int i; - ProcessInfo Process_Info = {10000, 12000, 55600}; - //ProcessInfo Process_Info = {156, 14000, 55500}; - GtkTreeRowReference *row_ref; - - LttTime birth; - - if(process_list->Test_Process_Sent) return; - - birth.tv_sec = 12000; - birth.tv_nsec = 55500; - - processlist_add(process_list, - 1, - &birth, - &y); - processlist_get_process_pixels(process_list, - 1, - &birth, - &y, - &height); - drawing_insert_square( drawing, y, height); - - //g_critical("y : %u, height : %u", y, height); - - birth.tv_sec = 14000; - birth.tv_nsec = 55500; - - processlist_add(process_list, - 156, - &birth, - &y); - processlist_get_process_pixels(process_list, - 156, - &birth, - &y, - &height); - drawing_insert_square( drawing, y, height); - - //g_critical("y : %u, height : %u", y, height); - - birth.tv_sec = 12000; - birth.tv_nsec = 55700; - - processlist_add(process_list, - 10, - &birth, - &height); - processlist_get_process_pixels(process_list, - 10, - &birth, - &y, - &height); - drawing_insert_square( drawing, y, height); - - //g_critical("y : %u, height : %u", y, height); - - //drawing_insert_square( drawing, height, 5); - - for(i=0; i<10; i++) - { - birth.tv_sec = i*12000; - birth.tv_nsec = i*55700; - - processlist_add(process_list, - i, - &birth, - &height); - processlist_get_process_pixels(process_list, - i, - &birth, - &y, - &height); - drawing_insert_square( drawing, y, height); - - // g_critical("y : %u, height : %u", y, height); - - } - //g_critical("height : %u", height); - - birth.tv_sec = 12000; - birth.tv_nsec = 55600; - - processlist_add(process_list, - 10, - &birth, - &y); - processlist_get_process_pixels(process_list, - 10, - &birth, - &y, - &height); - drawing_insert_square( drawing, y, height); - - //g_critical("y : %u, height : %u", y, height); - - processlist_add(process_list, - 10000, - &birth, - &height); - processlist_get_process_pixels(process_list, - 10000, - &birth, - &y, - &height); - drawing_insert_square( drawing, y, height); - - //g_critical("y : %u, height : %u", y, height); - - //drawing_insert_square( drawing, height, 5); - //g_critical("height : %u", height); - - - processlist_get_process_pixels(process_list, - 10000, - &birth, - &y, &height); - processlist_remove( process_list, - 10000, - &birth); - - drawing_remove_square( drawing, y, height); - - if(row_ref = - (GtkTreeRowReference*)g_hash_table_lookup( - process_list->process_hash, - &Process_Info)) - { - g_critical("key found"); - g_critical("position in the list : %s", - gtk_tree_path_to_string ( - gtk_tree_row_reference_get_path( - (GtkTreeRowReference*)row_ref) - )); - - } - - process_list->Test_Process_Sent = TRUE; - -} -#endif//NOTUSE - diff --git a/ltt/branches/poly/lttv/modules/guiEvents.c b/ltt/branches/poly/lttv/modules/guiEvents.c deleted file mode 100644 index feeb029f..00000000 --- a/ltt/branches/poly/lttv/modules/guiEvents.c +++ /dev/null @@ -1,1872 +0,0 @@ -//*! \defgroup GuiEvents libGuiEvents: The GUI Events display plugin */ -/*\@{*/ - -/*! \file GuiEvents.c - * \brief Graphical plugin for showing events. - * - * This plugin lists all the events contained in the current time interval - * in a list. - * - * This plugin adds a Events Viewer functionnality to Linux TraceToolkit - * GUI when this plugin is loaded. The init and destroy functions add the - * viewer's insertion menu item and toolbar icon by calling gtkTraceSet's - * API functions. Then, when a viewer's object is created, the constructor - * creates ans register through API functions what is needed to interact - * with the TraceSet window. - * - * Authors : Mathieu Desnoyers and XangXiu Yang, June to December 2003 - * Inspired from original LTT, made by Karim Yaghmour - */ - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//#include "mw_api.h" -#include "gtktreeprivate.h" - -#include "icons/hGuiEventsInsert.xpm" - - -static LttvHooks *before_event; - -/** Array containing instanced objects. Used when module is unloaded */ -static GSList *g_event_viewer_data_list = NULL ; - -typedef struct _RawTraceData{ - unsigned cpu_id; - char * event_name; - LttTime time; - int pid; - unsigned entry_length; - char * event_description; - LttEventPosition *ep; -} RawTraceData; - -#define RESERVE_BIG_SIZE 1000 -#define RESERVE_SMALL_SIZE 100 -#define RESERVE_SMALL_SIZE_SQUARE RESERVE_SMALL_SIZE*RESERVE_SMALL_SIZE -#define RESERVE_SMALL_SIZE_CUBE RESERVE_SMALL_SIZE*RESERVE_SMALL_SIZE_SQUARE - -typedef enum _ScrollDirection{ - SCROLL_STEP_UP, - SCROLL_STEP_DOWN, - SCROLL_PAGE_UP, - SCROLL_PAGE_DOWN, - SCROLL_JUMP, - SCROLL_NONE -} ScrollDirection; - -typedef struct _EventViewerData { - - MainWindow * mw; - TimeWindow time_window; - LttTime current_time; - LttvHooks * before_event_hooks; - - gboolean append; //prepend or append item - GQueue * raw_trace_data_queue; //buf to contain raw trace data - GQueue * raw_trace_data_queue_tmp; //tmp buf to contain raw data - unsigned current_event_index; - double previous_value; //value of the slide - TimeInterval time_span; - unsigned start_event_index; //the first event shown in the window - unsigned end_event_index; //the last event shown in the window - unsigned size; //maxi number of events loaded when instance the viewer - gboolean shown; //indicate if event detail is shown or not - gboolean current_time_updated; - char * filter_key; - - //scroll window containing Tree View - GtkWidget * scroll_win; - - /* Model containing list data */ - GtkListStore *store_m; - - GtkWidget *hbox_v; - /* Widget to display the data in a columned list */ - GtkWidget *tree_v; - GtkAdjustment *vtree_adjust_c ; - - /* Vertical scrollbar and it's adjustment */ - GtkWidget *vscroll_vc; - GtkAdjustment *vadjust_c ; - - /* Selection handler */ - GtkTreeSelection *select_c; - - guint num_visible_events; - guint first_event, last_event; - - /* TEST DATA, TO BE READ FROM THE TRACE */ - gint number_of_events ; - guint currently_selected_event ; - gboolean selected_event ; - -} EventViewerData ; - -/** hook functions for update time interval, current time ... */ -gboolean update_time_window(void * hook_data, void * call_data); -gboolean update_current_time(void * hook_data, void * call_data); -gboolean show_event_detail(void * hook_data, void * call_data); -gboolean traceset_changed(void * hook_data, void * call_data); -void remove_item_from_queue(GQueue * q, gboolean fromHead); -void remove_all_items_from_queue(GQueue * q); -void add_context_hooks(EventViewerData * event_viewer_data, - LttvTracesetContext * tsc); -void remove_context_hooks(EventViewerData * event_viewer_data, - LttvTracesetContext * tsc); - -//! Event Viewer's constructor hook -GtkWidget *h_gui_events(MainWindow *parent_window, LttvTracesetSelector * s, char* key); -//! Event Viewer's constructor -EventViewerData *gui_events(MainWindow *parent_window, LttvTracesetSelector *s, char *key); -//! Event Viewer's destructor -void gui_events_destructor(EventViewerData *event_viewer_data); -void gui_events_free(EventViewerData *event_viewer_data); - -static int event_selected_hook(void *hook_data, void *call_data); - -void tree_v_set_cursor(EventViewerData *event_viewer_data); -void tree_v_get_cursor(EventViewerData *event_viewer_data); - -/* Prototype for selection handler callback */ -static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data); -static void v_scroll_cb (GtkAdjustment *adjustment, gpointer data); -static void tree_v_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer data); -static void tree_v_size_request_cb (GtkWidget *widget, GtkRequisition *requisition, gpointer data); -static void tree_v_cursor_changed_cb (GtkWidget *widget, gpointer data); -static void tree_v_move_cursor_cb (GtkWidget *widget, GtkMovementStep arg1, gint arg2, gpointer data); -static void tree_v_grab_focus(GtkWidget *widget, gpointer data); - - -static void get_test_data(double time, guint list_height, - EventViewerData *event_viewer_data); - -void add_test_data(EventViewerData *event_viewer_data); - -static void update_raw_data_array(EventViewerData* event_viewer_data, unsigned size); - -static void get_events(EventViewerData* event_viewer_data, LttTime start, - LttTime end, unsigned max_num_events, unsigned * real_num_events); -static gboolean parse_event(void *hook_data, void *call_data); - -static LttvModule *main_win_module; - -/** - * plugin's init function - * - * This function initializes the Event Viewer functionnality through the - * gtkTraceSet API. - */ -G_MODULE_EXPORT void init(LttvModule *self, int argc, char *argv[]) { - - main_win_module = lttv_module_require(self, "mainwin", argc, argv); - - if(main_win_module == NULL){ - g_critical("Can't load Control Flow Viewer : missing mainwin\n"); - return; - } - - /* Register the toolbar insert button */ - toolbar_item_reg(hGuiEventsInsert_xpm, "Insert Event Viewer", h_gui_events); - - /* Register the menu item insert entry */ - menu_item_reg("/", "Insert Event Viewer", h_gui_events); - -} - -void event_destroy_walk(gpointer data, gpointer user_data) -{ - gui_events_destructor((EventViewerData*)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. - */ -G_MODULE_EXPORT void destroy() { - int i; - - EventViewerData *event_viewer_data; - - if(g_event_viewer_data_list){ - g_slist_foreach(g_event_viewer_data_list, event_destroy_walk, NULL ); - g_slist_free(g_event_viewer_data_list); - } - - /* Unregister the toolbar insert button */ - toolbar_item_unreg(h_gui_events); - - /* Unregister the menu item insert entry */ - menu_item_unreg(h_gui_events); -} - -/* Enumeration of the columns */ -enum -{ - CPUID_COLUMN, - EVENT_COLUMN, - TIME_COLUMN, - PID_COLUMN, - ENTRY_LEN_COLUMN, - EVENT_DESCR_COLUMN, - N_COLUMNS -}; - - -/** - * Event Viewer's constructor hook - * - * This constructor is given as a parameter to the menuitem and toolbar button - * registration. It creates the list. - * @param parent_window A pointer to the parent window. - * @return The widget created. - */ -GtkWidget * -h_gui_events(MainWindow * parent_window, LttvTracesetSelector * s, char* key) -{ - EventViewerData* event_viewer_data = gui_events(parent_window, s, key) ; - - if(event_viewer_data) - return event_viewer_data->hbox_v; - else return NULL; - -} - -/** - * Event Viewer's constructor - * - * This constructor is used to create EventViewerData data structure. - * @return The Event viewer data created. - */ -EventViewerData * -gui_events(MainWindow *parent_window, LttvTracesetSelector * s,char* key ) -{ - LttTime start, end; - GtkTreeViewColumn *column; - GtkCellRenderer *renderer; - EventViewerData* event_viewer_data = g_new(EventViewerData,1) ; - RawTraceData * data; - - event_viewer_data->mw = parent_window; - get_time_window(event_viewer_data->mw, &event_viewer_data->time_window); - get_current_time(event_viewer_data->mw, &event_viewer_data->current_time); - - event_viewer_data->before_event_hooks = lttv_hooks_new(); - lttv_hooks_add(event_viewer_data->before_event_hooks, parse_event, event_viewer_data); - - event_viewer_data->raw_trace_data_queue = g_queue_new(); - event_viewer_data->raw_trace_data_queue_tmp = g_queue_new(); - - reg_update_time_window(update_time_window,event_viewer_data, event_viewer_data->mw); - reg_update_current_time(update_current_time,event_viewer_data, event_viewer_data->mw); - reg_show_viewer(show_event_detail,event_viewer_data, event_viewer_data->mw); - reg_update_traceset(traceset_changed,event_viewer_data, event_viewer_data->mw); - - event_viewer_data->scroll_win = gtk_scrolled_window_new (NULL, NULL); - gtk_widget_show ( event_viewer_data->scroll_win); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(event_viewer_data->scroll_win), - GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER); - - /* TEST DATA, TO BE READ FROM THE TRACE */ - event_viewer_data->currently_selected_event = FALSE ; - event_viewer_data->selected_event = 0; - - /* Create a model for storing the data list */ - event_viewer_data->store_m = gtk_list_store_new ( - N_COLUMNS, /* Total number of columns */ - G_TYPE_INT, /* CPUID */ - G_TYPE_STRING, /* Event */ - G_TYPE_UINT64, /* Time */ - G_TYPE_INT, /* PID */ - G_TYPE_INT, /* Entry length */ - G_TYPE_STRING); /* Event's description */ - - /* Create the viewer widget for the columned list */ - event_viewer_data->tree_v = gtk_tree_view_new_with_model (GTK_TREE_MODEL (event_viewer_data->store_m)); - - g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "size-allocate", - G_CALLBACK (tree_v_size_allocate_cb), - event_viewer_data); - g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "size-request", - G_CALLBACK (tree_v_size_request_cb), - event_viewer_data); - - g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "cursor-changed", - G_CALLBACK (tree_v_cursor_changed_cb), - event_viewer_data); - - g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "move-cursor", - G_CALLBACK (tree_v_move_cursor_cb), - event_viewer_data); - - g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "grab-focus", - G_CALLBACK (tree_v_grab_focus), - event_viewer_data); - - // Use on each column! - //gtk_tree_view_column_set_sizing(event_viewer_data->tree_v, GTK_TREE_VIEW_COLUMN_FIXED); - - /* The view now holds a reference. We can get rid of our own - * reference */ - g_object_unref (G_OBJECT (event_viewer_data->store_m)); - - - /* Create a column, associating the "text" attribute of the - * cell_renderer to the first column of the model */ - /* Columns alignment : 0.0 : Left 0.5 : Center 1.0 : Right */ - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("CPUID", - renderer, - "text", CPUID_COLUMN, - NULL); - gtk_tree_view_column_set_alignment (column, 0.0); - gtk_tree_view_column_set_fixed_width (column, 45); - gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column); - - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("Event", - renderer, - "text", EVENT_COLUMN, - NULL); - gtk_tree_view_column_set_alignment (column, 0.0); - gtk_tree_view_column_set_fixed_width (column, 120); - gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column); - - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("Time", - renderer, - "text", TIME_COLUMN, - NULL); - gtk_tree_view_column_set_alignment (column, 1.0); - gtk_tree_view_column_set_fixed_width (column, 120); - gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column); - - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("PID", - renderer, - "text", PID_COLUMN, - NULL); - gtk_tree_view_column_set_alignment (column, 1.0); - gtk_tree_view_column_set_fixed_width (column, 45); - gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column); - - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("Entry Length", - renderer, - "text", ENTRY_LEN_COLUMN, - NULL); - gtk_tree_view_column_set_alignment (column, 1.0); - gtk_tree_view_column_set_fixed_width (column, 60); - gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column); - - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("Event's Description", - renderer, - "text", EVENT_DESCR_COLUMN, - NULL); - gtk_tree_view_column_set_alignment (column, 0.0); - gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column); - - - /* Setup the selection handler */ - event_viewer_data->select_c = gtk_tree_view_get_selection (GTK_TREE_VIEW (event_viewer_data->tree_v)); - gtk_tree_selection_set_mode (event_viewer_data->select_c, GTK_SELECTION_SINGLE); - g_signal_connect (G_OBJECT (event_viewer_data->select_c), "changed", - G_CALLBACK (tree_selection_changed_cb), - event_viewer_data); - - gtk_container_add (GTK_CONTAINER (event_viewer_data->scroll_win), event_viewer_data->tree_v); - - event_viewer_data->hbox_v = gtk_hbox_new(0, 0); - gtk_box_pack_start(GTK_BOX(event_viewer_data->hbox_v), event_viewer_data->scroll_win, TRUE, TRUE, 0); - - /* Create vertical scrollbar and pack it */ - event_viewer_data->vscroll_vc = gtk_vscrollbar_new(NULL); - gtk_range_set_update_policy (GTK_RANGE(event_viewer_data->vscroll_vc), - GTK_UPDATE_CONTINUOUS); - // Changed by MD : more user friendly :) - //GTK_UPDATE_DISCONTINUOUS); - gtk_box_pack_start(GTK_BOX(event_viewer_data->hbox_v), event_viewer_data->vscroll_vc, FALSE, TRUE, 0); - - /* Get the vertical scrollbar's adjustment */ - event_viewer_data->vadjust_c = gtk_range_get_adjustment(GTK_RANGE(event_viewer_data->vscroll_vc)); - event_viewer_data->vtree_adjust_c = gtk_tree_view_get_vadjustment( - GTK_TREE_VIEW (event_viewer_data->tree_v)); - - g_signal_connect (G_OBJECT (event_viewer_data->vadjust_c), "value-changed", - G_CALLBACK (v_scroll_cb), - event_viewer_data); - /* Set the upper bound to the last event number */ - event_viewer_data->previous_value = 0; - event_viewer_data->vadjust_c->lower = 0.0; - //event_viewer_data->vadjust_c->upper = event_viewer_data->number_of_events; - event_viewer_data->vadjust_c->value = 0.0; - event_viewer_data->vadjust_c->step_increment = 1.0; - event_viewer_data->vadjust_c->page_increment = 2.0; - // event_viewer_data->vtree_adjust_c->upper; - event_viewer_data->vadjust_c->page_size = 2.0; - // event_viewer_data->vtree_adjust_c->upper; - /* Raw event trace */ - gtk_widget_show(event_viewer_data->hbox_v); - gtk_widget_show(event_viewer_data->tree_v); - gtk_widget_show(event_viewer_data->vscroll_vc); - - /* Add the object's information to the module's array */ - g_event_viewer_data_list = g_slist_append(g_event_viewer_data_list, event_viewer_data); - - event_viewer_data->first_event = -1 ; - event_viewer_data->last_event = 0 ; - - event_viewer_data->num_visible_events = 1; - - //get the life span of the traceset and set the upper of the scroll bar - get_traceset_time_span(event_viewer_data->mw, &event_viewer_data->time_span); - - start = ltt_time_sub(event_viewer_data->time_span.endTime, event_viewer_data->time_span.startTime); - event_viewer_data->vadjust_c->upper = ltt_time_to_double(start) * NANOSECONDS_PER_SECOND; - - event_viewer_data->append = TRUE; - - event_viewer_data->start_event_index = 0; - event_viewer_data->end_event_index = event_viewer_data->num_visible_events - 1; - - /* Set the Selected Event */ - // tree_v_set_cursor(event_viewer_data); - - event_viewer_data->shown = FALSE; - event_viewer_data->current_time_updated = FALSE; - event_viewer_data->size = RESERVE_SMALL_SIZE; - g_object_set_data( - G_OBJECT(event_viewer_data->hbox_v), - MAX_NUMBER_EVENT, - &event_viewer_data->size); - - g_object_set_data( - G_OBJECT(event_viewer_data->hbox_v), - TRACESET_TIME_SPAN, - &event_viewer_data->time_span); - - event_viewer_data->filter_key = g_strdup(key); - g_object_set_data( - G_OBJECT(event_viewer_data->hbox_v), - event_viewer_data->filter_key, - s); - - g_object_set_data_full( - G_OBJECT(event_viewer_data->hbox_v), - "event_viewer_data", - event_viewer_data, - (GDestroyNotify)gui_events_free); - - return event_viewer_data; -} - -void tree_v_set_cursor(EventViewerData *event_viewer_data) -{ - GtkTreePath *path; - - if(event_viewer_data->selected_event && event_viewer_data->first_event != -1) - { - // gtk_adjustment_set_value(event_viewer_data->vadjust_c, - // event_viewer_data->currently_selected_event); - - path = gtk_tree_path_new_from_indices( - event_viewer_data->currently_selected_event- - event_viewer_data->first_event, - -1); - - gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE); - gtk_tree_path_free(path); - } -} - -void tree_v_get_cursor(EventViewerData *event_viewer_data) -{ - GtkTreePath *path; - gint *indices; - - gtk_tree_view_get_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), &path, NULL); - indices = gtk_tree_path_get_indices(path); - - if(indices != NULL) - { - event_viewer_data->selected_event = TRUE; - event_viewer_data->currently_selected_event = - event_viewer_data->first_event + indices[0]; - - } else { - event_viewer_data->selected_event = FALSE; - event_viewer_data->currently_selected_event = 0; - } - - gtk_tree_path_free(path); - -} - - - -void tree_v_move_cursor_cb (GtkWidget *widget, GtkMovementStep arg1, gint arg2, gpointer data) -{ - GtkTreePath *path; // = gtk_tree_path_new(); - gint *indices; - gdouble value; - EventViewerData *event_viewer_data = (EventViewerData*)data; - - gtk_tree_view_get_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), &path, NULL); - if(path == NULL) - { - /* No prior cursor, put it at beginning of page and let the execution do */ - path = gtk_tree_path_new_from_indices(0, -1); - gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE); - } - - indices = gtk_tree_path_get_indices(path); - - value = gtk_adjustment_get_value(event_viewer_data->vadjust_c); - - if(arg1 == GTK_MOVEMENT_DISPLAY_LINES) - { - /* Move one line */ - if(arg2 == 1) - { - /* move one line down */ - if(indices[0] == event_viewer_data->num_visible_events - 1) - { - if(value + event_viewer_data->num_visible_events <= - event_viewer_data->number_of_events -1) - { - event_viewer_data->currently_selected_event += 1; - // gtk_adjustment_set_value(event_viewer_data->vadjust_c, value+1); - //gtk_tree_path_free(path); - //path = gtk_tree_path_new_from_indices(event_viewer_data->num_visible_events-1, -1); - //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE); - g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor"); - } - } - } else { - /* Move one line up */ - if(indices[0] == 0) - { - if(value - 1 >= 0 ) - { - event_viewer_data->currently_selected_event -= 1; - // gtk_adjustment_set_value(event_viewer_data->vadjust_c, value-1); - //gtk_tree_path_free(path); - //path = gtk_tree_path_new_from_indices(0, -1); - //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE); - g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor"); - } - - } - } - - } - - if(arg1 == GTK_MOVEMENT_PAGES) - { - /* Move one page */ - if(arg2 == 1) - { - if(event_viewer_data->num_visible_events == 1) - value += 1 ; - /* move one page down */ - if(value + event_viewer_data->num_visible_events-1 <= - event_viewer_data->number_of_events ) - { - event_viewer_data->currently_selected_event += event_viewer_data->num_visible_events-1; - // gtk_adjustment_set_value(event_viewer_data->vadjust_c, - // value+(event_viewer_data->num_visible_events-1)); - //gtk_tree_path_free(path); - //path = gtk_tree_path_new_from_indices(0, -1); - //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE); - g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor"); - } - } else { - /* Move one page up */ - if(event_viewer_data->num_visible_events == 1) - value -= 1 ; - - if(indices[0] < event_viewer_data->num_visible_events - 2 ) - { - if(value - (event_viewer_data->num_visible_events-1) >= 0) - { - event_viewer_data->currently_selected_event -= event_viewer_data->num_visible_events-1; - - // gtk_adjustment_set_value(event_viewer_data->vadjust_c, - // value-(event_viewer_data->num_visible_events-1)); - //gtk_tree_path_free(path); - //path = gtk_tree_path_new_from_indices(0, -1); - //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE); - g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor"); - - } else { - /* Go to first Event */ - event_viewer_data->currently_selected_event == 0 ; - // gtk_adjustment_set_value(event_viewer_data->vadjust_c, - // 0); - //gtk_tree_path_free(path); - //path = gtk_tree_path_new_from_indices(0, -1); - //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE); - g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor"); - - } - } - - } - - } - - if(arg1 == GTK_MOVEMENT_BUFFER_ENDS) - { - /* Move to the ends of the buffer */ - if(arg2 == 1) - { - /* move end of buffer */ - event_viewer_data->currently_selected_event = event_viewer_data->number_of_events-1 ; - // gtk_adjustment_set_value(event_viewer_data->vadjust_c, - // event_viewer_data->number_of_events - - // event_viewer_data->num_visible_events); - //gtk_tree_path_free(path); - //path = gtk_tree_path_new_from_indices(event_viewer_data->num_visible_events-1, -1); - //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE); - g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor"); - } else { - /* Move beginning of buffer */ - event_viewer_data->currently_selected_event = 0 ; - // gtk_adjustment_set_value(event_viewer_data->vadjust_c, 0); - //gtk_tree_path_free(path); - //path = gtk_tree_path_new_from_indices(0, -1); - //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE); - g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor"); - } - - } - - - gtk_tree_path_free(path); -} - -void tree_v_cursor_changed_cb (GtkWidget *widget, gpointer data) -{ - EventViewerData *event_viewer_data = (EventViewerData*) data; - LttTime ltt_time; - guint64 time; - GtkTreeIter iter; - GtkTreeModel* model = GTK_TREE_MODEL(event_viewer_data->store_m); - GtkTreePath *path; - - /* On cursor change, modify the currently selected event by calling - * the right API function */ - tree_v_get_cursor(event_viewer_data); - - gtk_tree_view_get_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), &path, NULL); - if(gtk_tree_model_get_iter(model,&iter,path)){ - gtk_tree_model_get(model, &iter, TIME_COLUMN, &time, -1); - ltt_time.tv_sec = time / NANOSECONDS_PER_SECOND; - ltt_time.tv_nsec = time % NANOSECONDS_PER_SECOND; - - if(ltt_time.tv_sec != event_viewer_data->current_time.tv_sec || - ltt_time.tv_nsec != event_viewer_data->current_time.tv_nsec){ - event_viewer_data->current_time_updated = TRUE; - set_current_time(event_viewer_data->mw,<t_time); - } - }else{ - g_warning("Can not get iter\n"); - } - -} - - -void v_scroll_cb (GtkAdjustment *adjustment, gpointer data) -{ - EventViewerData *event_viewer_data = (EventViewerData*)data; - GtkTreePath *tree_path; - - get_test_data(adjustment->value, event_viewer_data->num_visible_events, - event_viewer_data); - - - if(event_viewer_data->currently_selected_event - >= event_viewer_data->first_event - && - event_viewer_data->currently_selected_event - <= event_viewer_data->last_event - && - event_viewer_data->selected_event) - { - - tree_path = gtk_tree_path_new_from_indices( - event_viewer_data->currently_selected_event- - event_viewer_data->first_event, - -1); - - // gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), tree_path, - // NULL, FALSE); - gtk_tree_path_free(tree_path); - } - - -} - -gint get_cell_height(GtkTreeView *TreeView) -{ - gint height, width; - GtkTreeViewColumn *column = gtk_tree_view_get_column(TreeView, 0); - GList *Render_List = gtk_tree_view_column_get_cell_renderers(column); - GtkCellRenderer *renderer = g_list_first(Render_List)->data; - - gtk_tree_view_column_cell_get_size(column, NULL, NULL, NULL, NULL, &height); - - return height; -} - -void tree_v_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer data) -{ - EventViewerData *event_viewer_data = (EventViewerData*)data; - gint cell_height = get_cell_height(GTK_TREE_VIEW(event_viewer_data->tree_v)); - gint last_num_visible_events = event_viewer_data->num_visible_events; - gdouble exact_num_visible; - - exact_num_visible = ( alloc->height - - TREE_VIEW_HEADER_HEIGHT (GTK_TREE_VIEW(event_viewer_data->tree_v)) ) - / (double)cell_height ; - - event_viewer_data->num_visible_events = ceil(exact_num_visible) ; - -/* - event_viewer_data->vadjust_c->page_increment = - floor(exact_num_visible); - event_viewer_data->vadjust_c->page_size = - floor(exact_num_visible); -*/ - - if(event_viewer_data->num_visible_events != last_num_visible_events) - { - get_test_data(event_viewer_data->vadjust_c->value, - event_viewer_data->num_visible_events, - event_viewer_data); - } - - -} - -void tree_v_size_request_cb (GtkWidget *widget, GtkRequisition *requisition, gpointer data) -{ - gint h; - EventViewerData *event_viewer_data = (EventViewerData*)data; - gint cell_height = get_cell_height(GTK_TREE_VIEW(event_viewer_data->tree_v)); - - h = cell_height + TREE_VIEW_HEADER_HEIGHT - (GTK_TREE_VIEW(event_viewer_data->tree_v)); - requisition->height = h; - -} - -gboolean show_event_detail(void * hook_data, void * call_data) -{ - EventViewerData *event_viewer_data = (EventViewerData*) hook_data; - LttvTracesetContext * tsc = get_traceset_context(event_viewer_data->mw); - - if(event_viewer_data->shown == FALSE){ - event_viewer_data->shown = TRUE; - update_raw_data_array(event_viewer_data, - event_viewer_data->raw_trace_data_queue_tmp->length); - - get_test_data(event_viewer_data->vadjust_c->value, - event_viewer_data->num_visible_events, - event_viewer_data); - - remove_context_hooks(event_viewer_data,tsc); - } - - return FALSE; -} - -void insert_data_into_model(EventViewerData *event_viewer_data, int start, int end) -{ - int i; - guint64 real_data; - RawTraceData * raw_data; - GList * first; - GtkTreeIter iter; - - first = event_viewer_data->raw_trace_data_queue->head; - for(i=start; i=event_viewer_data->number_of_events) break; - raw_data = (RawTraceData*)g_list_nth_data(first, i); - - // Add a new row to the model - real_data = raw_data->time.tv_sec; - real_data *= NANOSECONDS_PER_SECOND; - real_data += raw_data->time.tv_nsec; - gtk_list_store_append (event_viewer_data->store_m, &iter); - gtk_list_store_set (event_viewer_data->store_m, &iter, - CPUID_COLUMN, raw_data->cpu_id, - EVENT_COLUMN, raw_data->event_name, - TIME_COLUMN, real_data, - PID_COLUMN, raw_data->pid, - ENTRY_LEN_COLUMN, raw_data->entry_length, - EVENT_DESCR_COLUMN, raw_data->event_description, - -1); - } -} - -void get_test_data(double time_value, guint list_height, - EventViewerData *event_viewer_data) -{ - GtkTreeIter iter; - int i; - GtkTreeModel *model = GTK_TREE_MODEL(event_viewer_data->store_m); - GtkTreePath *tree_path; - RawTraceData * raw_data; - ScrollDirection direction = SCROLL_NONE; - GList * first; - int event_number; - double value = event_viewer_data->previous_value - time_value; - LttTime start, end, time; - LttEvent * ev; - unsigned backward_num, minNum, maxNum; - LttTracefile * tf; - unsigned block_num, event_num; - unsigned size = 1, count = 0; - gboolean need_backward_again, backward; - GdkWindow * win; - GdkCursor * new; - GtkWidget* widget = gtk_widget_get_parent(event_viewer_data->hbox_v); - - if(widget){ - new = gdk_cursor_new(GDK_X_CURSOR); - win = gtk_widget_get_parent_window(widget); - gdk_window_set_cursor(win, new); - gdk_cursor_unref(new); - gdk_window_stick(win); - gdk_window_unstick(win); - } - - - // if(event_number > event_viewer_data->last_event || - // event_number + list_height-1 < event_viewer_data->first_event || - // event_viewer_data->first_event == -1) - { - /* no event can be reused, clear and start from nothing */ - if(value == -1.0) direction = SCROLL_STEP_DOWN; - else if(value == 1.0 ) direction = SCROLL_STEP_UP; - else if(value == -2.0) direction = SCROLL_PAGE_DOWN; - else if(value == 2.0 ) direction = SCROLL_PAGE_UP; - else if(value == 0.0 ) direction = SCROLL_NONE; - else direction = SCROLL_JUMP; - - switch(direction){ - case SCROLL_STEP_UP: - case SCROLL_PAGE_UP: - if(direction == SCROLL_PAGE_UP){ - backward = list_height>event_viewer_data->start_event_index ? TRUE : FALSE; - }else{ - backward = event_viewer_data->start_event_index == 0 ? TRUE : FALSE; - } - if(backward){ - event_viewer_data->append = FALSE; - do{ - if(direction == SCROLL_PAGE_UP){ - minNum = list_height - event_viewer_data->start_event_index ; - }else{ - minNum = 1; - } - - first = event_viewer_data->raw_trace_data_queue->head; - if(!first)break; - raw_data = (RawTraceData*)g_list_nth_data(first,0); - end = raw_data->time; - end.tv_nsec--; - ltt_event_position_get(raw_data->ep, &block_num, &event_num, &tf); - if(size !=0){ - if(event_num > minNum){ - backward_num = event_num > RESERVE_SMALL_SIZE - ? event_num - RESERVE_SMALL_SIZE : 1; - ltt_event_position_set(raw_data->ep, block_num, backward_num); - ltt_tracefile_seek_position(tf, raw_data->ep); - ev = ltt_tracefile_read(tf); - start = ltt_event_time(ev); - maxNum = RESERVE_SMALL_SIZE_CUBE; - }else{ - if(block_num > 1){ - ltt_event_position_set(raw_data->ep, block_num-1, 1); - ltt_tracefile_seek_position(tf, raw_data->ep); - ev = ltt_tracefile_read(tf); - start = ltt_event_time(ev); - }else{ - start.tv_sec = 0; - start.tv_nsec = 0; - } - maxNum = RESERVE_SMALL_SIZE_CUBE; - } - }else{ - if(block_num > count){ - ltt_event_position_set(raw_data->ep, block_num-count, 1); - ltt_tracefile_seek_position(tf, raw_data->ep); - ev = ltt_tracefile_read(tf); - start = ltt_event_time(ev); - }else{ - start.tv_sec = 0; - start.tv_nsec = 0; - } - maxNum = RESERVE_SMALL_SIZE_CUBE; - } - - event_viewer_data->current_event_index = event_viewer_data->start_event_index; - get_events(event_viewer_data, start, end, maxNum, &size); - event_viewer_data->start_event_index = event_viewer_data->current_event_index; - - if(size < minNum && (start.tv_sec !=0 || start.tv_nsec !=0)) - need_backward_again = TRUE; - else need_backward_again = FALSE; - if(size == 0){ - count++; - }else{ - count = 0; - } - }while(need_backward_again); - } - if(direction == SCROLL_STEP_UP) - event_number = event_viewer_data->start_event_index - 1; - else - event_number = event_viewer_data->start_event_index - list_height; - break; - case SCROLL_STEP_DOWN: - if(event_viewer_data->end_event_index == event_viewer_data->number_of_events - 1){ - event_viewer_data->append = TRUE; - first = event_viewer_data->raw_trace_data_queue->head; - if(!first)break; - raw_data = (RawTraceData*)g_list_nth_data(first,event_viewer_data->number_of_events - 1); - start = raw_data->time; - start.tv_nsec++; - end.tv_sec = G_MAXULONG; - end.tv_nsec = G_MAXULONG; - get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE, &size); - if(size == 0){ - get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_SQUARE,&size); - if(size == 0) - get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_CUBE,&size); - } - if(size==0) event_number = event_viewer_data->start_event_index; - else event_number = event_viewer_data->number_of_events - size - list_height + 1; - }else event_number = event_viewer_data->start_event_index + 1; - break; - case SCROLL_PAGE_DOWN: - i = event_viewer_data->number_of_events - 1 - list_height; - if((gint)(event_viewer_data->end_event_index) >= i){ - int remain_events = event_viewer_data->number_of_events - 1 - - event_viewer_data->end_event_index; - event_viewer_data->append = TRUE; - first = event_viewer_data->raw_trace_data_queue->head; - if(!first)break; - raw_data = (RawTraceData*)g_list_nth_data(first,event_viewer_data->number_of_events - 1); - start = raw_data->time; - start.tv_nsec++; - end.tv_sec = G_MAXULONG; - end.tv_nsec = G_MAXULONG; - get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE,&size); - if(size == 0){ - get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_SQUARE,&size); - if(size == 0) - get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_CUBE,&size); - } - remain_events += size; - if(list_height <= remain_events) - event_number = event_viewer_data->number_of_events - remain_events - 1; - else - event_number = event_viewer_data->number_of_events - 1 - list_height; - }else event_number = event_viewer_data->start_event_index + list_height - 1; - break; - case SCROLL_JUMP: - event_viewer_data->append = TRUE; - remove_all_items_from_queue(event_viewer_data->raw_trace_data_queue); - end.tv_sec = G_MAXULONG; - end.tv_nsec = G_MAXULONG; - time = ltt_time_from_double(time_value / NANOSECONDS_PER_SECOND); - start = ltt_time_add(event_viewer_data->time_span.startTime, time); - event_viewer_data->previous_value = time_value; - get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE,&size); - if(size < list_height && size > 0){ - event_viewer_data->append = FALSE; - first = event_viewer_data->raw_trace_data_queue->head; - if(!first)break; - raw_data = (RawTraceData*)g_list_nth_data(first,0); - end = raw_data->time; - end.tv_nsec--; - ltt_event_position_get(raw_data->ep, &block_num, &event_num, &tf); - - if(event_num > list_height - size){ - backward_num = event_num > RESERVE_SMALL_SIZE - ? event_num - RESERVE_SMALL_SIZE : 1; - ltt_event_position_set(raw_data->ep, block_num, backward_num); - ltt_tracefile_seek_position(tf, raw_data->ep); - ev = ltt_tracefile_read(tf); - start = ltt_event_time(ev); - maxNum = RESERVE_SMALL_SIZE_CUBE; - event_viewer_data->current_event_index = 0; - get_events(event_viewer_data, start, end, maxNum, &size); - event_viewer_data->start_event_index = event_viewer_data->current_event_index; - } - event_number = event_viewer_data->raw_trace_data_queue->length - list_height; - }else if(size == 0){ - get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_SQUARE,&size); - if(size == 0) - get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_CUBE,&size); - event_number = 0; - }else{ - event_number = 0; - } - break; - case SCROLL_NONE: - event_number = event_viewer_data->current_event_index; - break; - default: - break; - } - - if(event_number < 0) event_number = 0; - - //update the value of the scroll bar - if(direction != SCROLL_NONE && direction != SCROLL_JUMP){ - first = event_viewer_data->raw_trace_data_queue->head; - if(first){ - raw_data = (RawTraceData*)g_list_nth_data(first,event_number); - if(!raw_data) raw_data = (RawTraceData*)g_list_nth_data(first,0); - time = ltt_time_sub(raw_data->time, event_viewer_data->time_span.startTime); - event_viewer_data->vadjust_c->value = ltt_time_to_double(time) * NANOSECONDS_PER_SECOND; - g_signal_stop_emission_by_name(G_OBJECT(event_viewer_data->vadjust_c), "value-changed"); - event_viewer_data->previous_value = event_viewer_data->vadjust_c->value; - } - } - - - event_viewer_data->start_event_index = event_number; - event_viewer_data->end_event_index = event_number + list_height - 1; - if(event_viewer_data->end_event_index > event_viewer_data->number_of_events - 1){ - event_viewer_data->end_event_index = event_viewer_data->number_of_events - 1; - } - - first = event_viewer_data->raw_trace_data_queue->head; - gtk_list_store_clear(event_viewer_data->store_m); - if(!first){ - // event_viewer_data->previous_value = 0; - // event_viewer_data->vadjust_c->value = 0.0; - // gtk_widget_hide(event_viewer_data->vscroll_vc); - goto LAST; - }else gtk_widget_show(event_viewer_data->vscroll_vc); - - insert_data_into_model(event_viewer_data,event_number, event_number+list_height); - } -#ifdef DEBUG //do not use this, it's slower and broken - // } else { - /* Some events will be reused */ - if(event_number < event_viewer_data->first_event) - { - /* scrolling up, prepend events */ - tree_path = gtk_tree_path_new_from_indices - (event_number+list_height-1 - - event_viewer_data->first_event + 1, - -1); - for(i=0; ilast_event-(event_number+list_height-1); - i++) - { - /* Remove the last events from the list */ - if(gtk_tree_model_get_iter(model, &iter, tree_path)) - gtk_list_store_remove(event_viewer_data->store_m, &iter); - } - - for(i=event_viewer_data->first_event-1; i>=event_number; i--) - { - if(i>=event_viewer_data->number_of_events) break; - /* Prepend new events */ - gtk_list_store_prepend (event_viewer_data->store_m, &iter); - gtk_list_store_set (event_viewer_data->store_m, &iter, - CPUID_COLUMN, 0, - EVENT_COLUMN, "event irq", - TIME_COLUMN, i, - PID_COLUMN, 100, - ENTRY_LEN_COLUMN, 17, - EVENT_DESCR_COLUMN, "Detailed information", - -1); - } - } else { - /* Scrolling down, append events */ - for(i=event_viewer_data->first_event; istore_m, &iter); - } - for(i=event_viewer_data->last_event+1; i=event_viewer_data->number_of_events) break; - /* Append new events */ - gtk_list_store_append (event_viewer_data->store_m, &iter); - gtk_list_store_set (event_viewer_data->store_m, &iter, - CPUID_COLUMN, 0, - EVENT_COLUMN, "event irq", - TIME_COLUMN, i, - PID_COLUMN, 100, - ENTRY_LEN_COLUMN, 17, - EVENT_DESCR_COLUMN, "Detailed information", - -1); - } - - } - //} -#endif //DEBUG - event_viewer_data->first_event = event_viewer_data->start_event_index ; - event_viewer_data->last_event = event_viewer_data->end_event_index ; - - LAST: - if(widget) - gdk_window_set_cursor(win, NULL); - -} - - -void add_test_data(EventViewerData *event_viewer_data) -{ - GtkTreeIter iter; - int i; - - for(i=0; i<10; i++) - { - /* Add a new row to the model */ - gtk_list_store_append (event_viewer_data->store_m, &iter); - gtk_list_store_set (event_viewer_data->store_m, &iter, - CPUID_COLUMN, 0, - EVENT_COLUMN, "event irq", - TIME_COLUMN, i, - PID_COLUMN, 100, - ENTRY_LEN_COLUMN, 17, - EVENT_DESCR_COLUMN, "Detailed information", - -1); - } - -} - -void -gui_events_free(EventViewerData *event_viewer_data) -{ - if(event_viewer_data){ - lttv_hooks_remove(event_viewer_data->before_event_hooks,parse_event); - lttv_hooks_destroy(event_viewer_data->before_event_hooks); - - remove_all_items_from_queue (event_viewer_data->raw_trace_data_queue); - g_queue_free(event_viewer_data->raw_trace_data_queue); - g_queue_free(event_viewer_data->raw_trace_data_queue_tmp); - - unreg_update_time_window(update_time_window,event_viewer_data, event_viewer_data->mw); - unreg_update_current_time(update_current_time,event_viewer_data, event_viewer_data->mw); - unreg_show_viewer(show_event_detail,event_viewer_data, event_viewer_data->mw); - unreg_update_traceset(traceset_changed,event_viewer_data, event_viewer_data->mw); - - g_event_viewer_data_list = g_slist_remove(g_event_viewer_data_list, event_viewer_data); - g_free(event_viewer_data); - } -} - -void -gui_events_destructor(EventViewerData *event_viewer_data) -{ - guint index; - - /* May already been done by GTK window closing */ - if(GTK_IS_WIDGET(event_viewer_data->hbox_v)){ - gtk_widget_destroy(event_viewer_data->hbox_v); - g_free(event_viewer_data->filter_key); - event_viewer_data = NULL; - } - - /* Destroy the Tree View */ - //gtk_widget_destroy(event_viewer_data->tree_v); - - /* Clear raw event list */ - //gtk_list_store_clear(event_viewer_data->store_m); - //gtk_widget_destroy(GTK_WIDGET(event_viewer_data->store_m)); - - //gui_events_free(event_viewer_data); -} - -//FIXME : call hGuiEvents_Destructor for corresponding data upon widget destroy - -static void -tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data) -{ - EventViewerData *event_viewer_data = (EventViewerData*)data; - GtkTreeIter iter; - GtkTreeModel *model = GTK_TREE_MODEL(event_viewer_data->store_m); - gchar *event; - - if (gtk_tree_selection_get_selected (selection, &model, &iter)) - { - gtk_tree_model_get (model, &iter, EVENT_COLUMN, &event, -1); - - g_free (event); - } -} - - -int event_selected_hook(void *hook_data, void *call_data) -{ - EventViewerData *event_viewer_data = (EventViewerData*) hook_data; - guint *event_number = (guint*) call_data; - - event_viewer_data->currently_selected_event = *event_number; - event_viewer_data->selected_event = TRUE ; - - tree_v_set_cursor(event_viewer_data); - -} - -/* If every module uses the filter, maybe these two - * (add/remove_context_hooks functions) should be put in common place - */ -void add_context_hooks(EventViewerData * event_viewer_data, - LttvTracesetContext * tsc) -{ - gint i, j, k, m,n, nbi, id; - gint nb_tracefile, nb_control, nb_per_cpu, nb_facility, nb_event; - LttTrace *trace; - LttvTraceContext *tc; - LttvTracefileContext *tfc; - LttvTracesetSelector * ts_s; - LttvTraceSelector * t_s; - LttvTracefileSelector * tf_s; - gboolean selected; - LttFacility * fac; - LttEventType * et; - LttvEventtypeSelector * eventtype; - - ts_s = (LttvTracesetSelector*)g_object_get_data(G_OBJECT(event_viewer_data->hbox_v), - event_viewer_data->filter_key); - - //if there are hooks for traceset, add them here - - nbi = lttv_traceset_number(tsc->ts); - for(i = 0 ; i < nbi ; i++) { - t_s = lttv_traceset_selector_trace_get(ts_s,i); - selected = lttv_trace_selector_get_selected(t_s); - if(!selected) continue; - tc = tsc->traces[i]; - trace = tc->t; - //if there are hooks for trace, add them here - - nb_control = ltt_trace_control_tracefile_number(trace); - nb_per_cpu = ltt_trace_per_cpu_tracefile_number(trace); - nb_tracefile = nb_control + nb_per_cpu; - - for(j = 0 ; j < nb_tracefile ; j++) { - tf_s = lttv_trace_selector_tracefile_get(t_s,j); - selected = lttv_tracefile_selector_get_selected(tf_s); - if(!selected) continue; - - if(j < nb_control) - tfc = tc->control_tracefiles[j]; - else - tfc = tc->per_cpu_tracefiles[j - nb_control]; - - //if there are hooks for tracefile, add them here - // lttv_tracefile_context_add_hooks(tfc, NULL,NULL,NULL,NULL, - // event_viewer_data->before_event_hooks,NULL); - - nb_facility = ltt_trace_facility_number(trace); - n = 0; - for(k=0;kbefore_event_hooks, - NULL); - } - n++; - } - } - - } - } - - //add hooks for process_traceset - // context_add_hooks_api(event_viewer_data->mw, NULL, NULL, NULL, NULL, NULL, NULL, - // NULL, NULL, NULL,event_viewer_data->before_event_hooks,NULL); -} - - -void remove_context_hooks(EventViewerData * event_viewer_data, - LttvTracesetContext * tsc) -{ - gint i, j, k, m, nbi, n, id; - gint nb_tracefile, nb_control, nb_per_cpu, nb_facility, nb_event; - LttTrace *trace; - LttvTraceContext *tc; - LttvTracefileContext *tfc; - LttvTracesetSelector * ts_s; - LttvTraceSelector * t_s; - LttvTracefileSelector * tf_s; - gboolean selected; - LttFacility * fac; - LttEventType * et; - LttvEventtypeSelector * eventtype; - - ts_s = (LttvTracesetSelector*)g_object_get_data(G_OBJECT(event_viewer_data->hbox_v), - event_viewer_data->filter_key); - - //if there are hooks for traceset, remove them here - - nbi = lttv_traceset_number(tsc->ts); - for(i = 0 ; i < nbi ; i++) { - t_s = lttv_traceset_selector_trace_get(ts_s,i); - selected = lttv_trace_selector_get_selected(t_s); - if(!selected) continue; - tc = tsc->traces[i]; - trace = tc->t; - //if there are hooks for trace, remove them here - - nb_control = ltt_trace_control_tracefile_number(trace); - nb_per_cpu = ltt_trace_per_cpu_tracefile_number(trace); - nb_tracefile = nb_control + nb_per_cpu; - - for(j = 0 ; j < nb_tracefile ; j++) { - tf_s = lttv_trace_selector_tracefile_get(t_s,j); - selected = lttv_tracefile_selector_get_selected(tf_s); - if(!selected) continue; - - if(j < nb_control) - tfc = tc->control_tracefiles[j]; - else - tfc = tc->per_cpu_tracefiles[j - nb_control]; - - //if there are hooks for tracefile, remove them here - // lttv_tracefile_context_remove_hooks(tfc, NULL,NULL,NULL,NULL, - // event_viewer_data->before_event_hooks,NULL); - - nb_facility = ltt_trace_facility_number(trace); - n = 0; - for(k=0;kmw, NULL, NULL, NULL, NULL, NULL, NULL, - // NULL, NULL, NULL,event_viewer_data->before_event_hooks,NULL); -} - - -gboolean update_time_window(void * hook_data, void * call_data) -{ - EventViewerData *event_viewer_data = (EventViewerData*) hook_data; - LttvTracesetContext * tsc = get_traceset_context(event_viewer_data->mw); - - if(event_viewer_data->shown == FALSE){ - event_viewer_data->time_window = *(TimeWindow*)call_data; - - add_context_hooks(event_viewer_data, tsc); - } - - return FALSE; -} - -gboolean update_current_time(void * hook_data, void * call_data) -{ - EventViewerData *event_viewer_data = (EventViewerData*) hook_data; - event_viewer_data->current_time = *(LttTime*)call_data; - guint64 nsec = event_viewer_data->current_time.tv_sec * NANOSECONDS_PER_SECOND - + event_viewer_data->current_time.tv_nsec; - GtkTreeIter iter; - guint64 time; - int count = -1; - GtkTreeModel* model = (GtkTreeModel*)event_viewer_data->store_m; - GList * list; - RawTraceData * data, *data1; - GtkTreePath* path; - char str_path[64]; - int i, j; - LttTime t; - - if(event_viewer_data->current_time_updated ){ - event_viewer_data->current_time_updated = FALSE; - return FALSE; - } - - //check if the event is shown in the current viewer - if(gtk_tree_model_get_iter_first(model, &iter)){ - while(1){ - gtk_tree_model_get(model, &iter, TIME_COLUMN, &time, -1); - if(time < nsec){ - if(!gtk_tree_model_iter_next(model, &iter)){ - count = -1; - break; - } - count++; - }else{ - break; - } - } - // event_selected_hook(event_viewer_data, &count); - } - - //the event is not shown in the current viewer - if(count == -1){ - count = 0; - //check if the event is in the buffer - list = event_viewer_data->raw_trace_data_queue->head; - data = (RawTraceData*)g_list_nth_data(list,0); - data1 = (RawTraceData*)g_list_nth_data(list,event_viewer_data->raw_trace_data_queue->length-1); - - //the event is in the buffer - if(ltt_time_compare(data->time, event_viewer_data->current_time)<=0 && - ltt_time_compare(data1->time, event_viewer_data->current_time)>=0){ - for(i=0;iraw_trace_data_queue->length;i++){ - data = (RawTraceData*)g_list_nth_data(list,i); - if(ltt_time_compare(data->time, event_viewer_data->current_time) < 0){ - count++; - continue; - } - break; - } - if(event_viewer_data->raw_trace_data_queue->length-count < event_viewer_data->num_visible_events){ - j = event_viewer_data->raw_trace_data_queue->length - event_viewer_data->num_visible_events; - count -= j; - data = (RawTraceData*)g_list_nth_data(list,j); - }else{ - j = count; - count = 0; - } - t = ltt_time_sub(data->time, event_viewer_data->time_span.startTime); - event_viewer_data->vadjust_c->value = ltt_time_to_double(t) * NANOSECONDS_PER_SECOND; - g_signal_stop_emission_by_name(G_OBJECT(event_viewer_data->vadjust_c), "value-changed"); - event_viewer_data->previous_value = event_viewer_data->vadjust_c->value; - insert_data_into_model(event_viewer_data,j, j+event_viewer_data->num_visible_events); - }else{//the event is not in the buffer - LttTime start = ltt_time_sub(event_viewer_data->current_time, event_viewer_data->time_span.startTime); - double position = ltt_time_to_double(start) * NANOSECONDS_PER_SECOND; - gtk_adjustment_set_value(event_viewer_data->vadjust_c, position); - } - } - - sprintf(str_path,"%d\0",count); - path = gtk_tree_path_new_from_string (str_path); - gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE); - g_signal_stop_emission_by_name(G_OBJECT(event_viewer_data->tree_v), "cursor-changed"); - gtk_tree_path_free(path); - - return FALSE; -} - -gboolean traceset_changed(void * hook_data, void * call_data) -{ - EventViewerData *event_viewer_data = (EventViewerData*) hook_data; - LttTime start; - - remove_all_items_from_queue(event_viewer_data->raw_trace_data_queue); - gtk_list_store_clear(event_viewer_data->store_m); - event_viewer_data->shown = FALSE; - event_viewer_data->append = TRUE; - - get_traceset_time_span(event_viewer_data->mw, &event_viewer_data->time_span); - start = ltt_time_sub(event_viewer_data->time_span.endTime, event_viewer_data->time_span.startTime); - event_viewer_data->vadjust_c->upper = ltt_time_to_double(start) * NANOSECONDS_PER_SECOND; - // event_viewer_data->vadjust_c->value = 0; - - return FALSE; -} - - -void tree_v_grab_focus(GtkWidget *widget, gpointer data){ - EventViewerData *event_viewer_data = (EventViewerData *)data; - MainWindow * mw = event_viewer_data->mw; - set_focused_pane(mw, gtk_widget_get_parent(event_viewer_data->hbox_v)); -} - -void update_raw_data_array(EventViewerData* event_viewer_data, unsigned size) -{ - RawTraceData * data; - if(size > 0){ - int pid, tmpPid, i,j,len; - GList * list, *tmpList; - GArray * pid_array, * tmp_pid_array; - - pid_array = g_array_sized_new(FALSE, TRUE, sizeof(int), 10); - tmp_pid_array = g_array_sized_new(FALSE, TRUE, sizeof(int), 10); - - //if the queue is full, remove some data, keep the size of the queue constant - while(event_viewer_data->raw_trace_data_queue->length + size > RESERVE_BIG_SIZE){ - remove_item_from_queue(event_viewer_data->raw_trace_data_queue, - event_viewer_data->append); - } - - //update pid if it is not known - if(event_viewer_data->raw_trace_data_queue->length > 0){ - list = event_viewer_data->raw_trace_data_queue->head; - tmpList = event_viewer_data->raw_trace_data_queue_tmp->head; - if(event_viewer_data->append){ - for(i= event_viewer_data->raw_trace_data_queue->length-1;i>=0;i--){ - data = (RawTraceData*)g_list_nth_data(list,i); - len = data->pid==0 ? -2 : data->pid; - if(data->cpu_id+1 > pid_array->len){ - pid_array = g_array_set_size(pid_array,data->cpu_id+1); - pid_array = g_array_insert_val(pid_array,data->cpu_id,len); - pid_array = g_array_remove_index(pid_array,data->cpu_id+1); - }else if(data->cpu_id+1 < pid_array->len){ - pid = g_array_index(pid_array,int,data->cpu_id); - if(pid == 0){ - pid_array = g_array_insert_val(pid_array,data->cpu_id,len); - pid_array = g_array_remove_index(pid_array,data->cpu_id+1); - } - } - } - - for(i=0;iraw_trace_data_queue_tmp->length;i++){ - data = (RawTraceData*)g_list_nth_data(tmpList,i); - len = data->pid==0 ? -2 : data->pid; - if(data->cpu_id+1 > tmp_pid_array->len){ - tmp_pid_array = g_array_set_size(tmp_pid_array,data->cpu_id+1); - tmp_pid_array = g_array_insert_val(tmp_pid_array,data->cpu_id,len); - tmp_pid_array = g_array_remove_index(tmp_pid_array,data->cpu_id+1); - }else if(data->cpu_id+1 < tmp_pid_array->len){ - pid = g_array_index(tmp_pid_array,int,data->cpu_id); - if(pid == 0){ - tmp_pid_array = g_array_insert_val(tmp_pid_array,data->cpu_id,len); - tmp_pid_array = g_array_remove_index(tmp_pid_array,data->cpu_id+1); - } - } - } - }else{ - for(i=0;iraw_trace_data_queue->length;i++){ - data = (RawTraceData*)g_list_nth_data(list,i); - len = data->pid==0 ? -2 : data->pid; - if(data->cpu_id+1 > pid_array->len){ - pid_array = g_array_set_size(pid_array,data->cpu_id+1); - pid_array = g_array_insert_val(pid_array,data->cpu_id,len); - pid_array = g_array_remove_index(pid_array,data->cpu_id+1); - }else if(data->cpu_id+1 < pid_array->len){ - pid = g_array_index(pid_array,int,data->cpu_id); - if(pid == 0){ - pid_array = g_array_insert_val(pid_array,data->cpu_id,len); - pid_array = g_array_remove_index(pid_array,data->cpu_id+1); - } - } - } - - for(i=event_viewer_data->raw_trace_data_queue_tmp->length-1;i>=0;i--){ - data = (RawTraceData*)g_list_nth_data(tmpList,i); - len = data->pid==0 ? -2 : data->pid; - if(data->cpu_id+1 > tmp_pid_array->len){ - tmp_pid_array = g_array_set_size(tmp_pid_array,data->cpu_id+1); - tmp_pid_array = g_array_insert_val(tmp_pid_array,data->cpu_id,len); - tmp_pid_array = g_array_remove_index(tmp_pid_array,data->cpu_id+1); - }else if(data->cpu_id+1 < tmp_pid_array->len){ - pid = g_array_index(tmp_pid_array,int,data->cpu_id); - if(pid == 0){ - tmp_pid_array = g_array_insert_val(tmp_pid_array,data->cpu_id,len); - tmp_pid_array = g_array_remove_index(tmp_pid_array,data->cpu_id+1); - } - } - } - } - - len = pid_array->len > tmp_pid_array->len ? tmp_pid_array->len : pid_array->len; - for(j=0;jraw_trace_data_queue->length;i++){ - data = (RawTraceData*)g_list_nth_data(list,i); - if(data->pid == -1 && data->cpu_id == j) data->pid = tmpPid; - } - }else if(pid != -1 && tmpPid == -1){ - for(i=0;iraw_trace_data_queue_tmp->length;i++){ - data = (RawTraceData*)g_list_nth_data(tmpList,i); - if(data->pid == -1 && data->cpu_id == j) data->pid = pid; - } - } - } - } - - g_array_free(pid_array,TRUE); - g_array_free(tmp_pid_array, TRUE); - - //add data from tmp queue into the queue - event_viewer_data->number_of_events = event_viewer_data->raw_trace_data_queue->length - + event_viewer_data->raw_trace_data_queue_tmp->length; - if(event_viewer_data->append){ - if(event_viewer_data->raw_trace_data_queue->length > 0) - event_viewer_data->current_event_index = event_viewer_data->raw_trace_data_queue->length - 1; - else event_viewer_data->current_event_index = 0; - while((data = g_queue_pop_head(event_viewer_data->raw_trace_data_queue_tmp)) != NULL){ - g_queue_push_tail(event_viewer_data->raw_trace_data_queue, data); - } - }else{ - event_viewer_data->current_event_index += event_viewer_data->raw_trace_data_queue_tmp->length; - while((data = g_queue_pop_tail(event_viewer_data->raw_trace_data_queue_tmp)) != NULL){ - g_queue_push_head(event_viewer_data->raw_trace_data_queue, data); - } - } - } -} - -void get_events(EventViewerData* event_viewer_data, LttTime start, - LttTime end,unsigned max_num_events, unsigned * real_num_events) -{ - int size; - LttvTracesetContext * tsc = get_traceset_context(event_viewer_data->mw); - - // context_add_hooks_api(event_viewer_data->mw, NULL, NULL, NULL, NULL, NULL, NULL, - // NULL, NULL, NULL,event_viewer_data->before_event_hooks,NULL); - add_context_hooks(event_viewer_data,tsc); - - process_traceset_api(event_viewer_data->mw, start, end, max_num_events); - - remove_context_hooks(event_viewer_data,tsc); - // context_remove_hooks_api(event_viewer_data->mw, NULL, NULL, NULL, NULL, NULL, NULL, - // NULL, NULL, NULL,event_viewer_data->before_event_hooks,NULL); - - size = event_viewer_data->raw_trace_data_queue_tmp->length; - *real_num_events = size; - - update_raw_data_array(event_viewer_data,size); -} - -static void get_event_detail(LttEvent *e, LttField *f, GString * s) -{ - LttType *type; - LttField *element; - char *name; - int nb, i; - - type = ltt_field_type(f); - switch(ltt_type_class(type)) { - case LTT_INT: - g_string_append_printf(s, " %ld", ltt_event_get_long_int(e,f)); - break; - - case LTT_UINT: - g_string_append_printf(s, " %lu", ltt_event_get_long_unsigned(e,f)); - break; - - case LTT_FLOAT: - g_string_append_printf(s, " %g", ltt_event_get_double(e,f)); - break; - - case LTT_STRING: - g_string_append_printf(s, " \"%s\"", ltt_event_get_string(e,f)); - break; - - case LTT_ENUM: - g_string_append_printf(s, " %s", ltt_enum_string_get(type, - ltt_event_get_unsigned(e,f)-1)); - break; - - case LTT_ARRAY: - case LTT_SEQUENCE: - g_string_append_printf(s, " {"); - nb = ltt_event_field_element_number(e,f); - element = ltt_field_element(f); - for(i = 0 ; i < nb ; i++) { - ltt_event_field_element_select(e,f,i); - get_event_detail(e, element, s); - } - g_string_append_printf(s, " }"); - break; - - case LTT_STRUCT: - g_string_append_printf(s, " {"); - nb = ltt_type_member_number(type); - for(i = 0 ; i < nb ; i++) { - element = ltt_field_member(f,i); - ltt_type_member_type(type, i, &name); - g_string_append_printf(s, " %s = ", name); - get_event_detail(e, element, s); - } - g_string_append_printf(s, " }"); - break; - } - -} - -static void get_pid(unsigned * in, unsigned * out, char * s) -{ - char * str; - str = strstr(s, "out ="); - if (str){ - str = str + 5; - sscanf(str,"%d", out); - }else{ - g_warning("Can not find out pid\n"); - } - - str = strstr(s,"in ="); - if (str){ - str = str + 4; - sscanf(str,"%d", in); - }else{ - g_warning("Can not find in pid\n"); - } -} - -gboolean parse_event(void *hook_data, void *call_data) -{ - EventViewerData *event_viewer_data = (EventViewerData *)hook_data; - LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; - LttvTracefileState *tfs = (LttvTracefileState *)call_data; - - RawTraceData * tmp_raw_trace_data,*prev_raw_trace_data = NULL, *data=NULL; - LttEvent *e; - LttTime time; - LttField * field; - unsigned in=0, out=0; - int i; - GString * detail_event = g_string_new(""); - GList * list; - - e = tfc->e; - field = ltt_event_field(e); - time = ltt_event_time(e); - - tmp_raw_trace_data = g_new(RawTraceData,1); - tmp_raw_trace_data->cpu_id = ltt_event_cpu_id(e); - tmp_raw_trace_data->event_name = g_strdup(ltt_eventtype_name(ltt_event_eventtype(e))); - tmp_raw_trace_data->time = time; - tmp_raw_trace_data->ep = ltt_event_position_new(); - - if(event_viewer_data->raw_trace_data_queue_tmp->length){ - list = event_viewer_data->raw_trace_data_queue_tmp->head; - for(i=event_viewer_data->raw_trace_data_queue_tmp->length-1;i>=0;i--){ - data = (RawTraceData *)g_list_nth_data(list,i); - if(data->cpu_id == tmp_raw_trace_data->cpu_id){ - prev_raw_trace_data = data; - break; - } - } - } - - if(prev_raw_trace_data) tmp_raw_trace_data->pid = prev_raw_trace_data->pid; - else tmp_raw_trace_data->pid = -1; - - tmp_raw_trace_data->entry_length = field == NULL ? 0 : ltt_field_size(field); - if(field) get_event_detail(e, field, detail_event); - tmp_raw_trace_data->event_description = g_strdup(detail_event->str); - - if(strcmp(tmp_raw_trace_data->event_name, "schedchange") == 0){ - get_pid(&in, &out, detail_event->str); - } - - - if(in != 0 || out != 0){ - tmp_raw_trace_data->pid = in; - if(prev_raw_trace_data && prev_raw_trace_data->pid == -1){ - list = event_viewer_data->raw_trace_data_queue_tmp->head; - for(i=0;iraw_trace_data_queue_tmp->length;i++){ - data = (RawTraceData *)g_list_nth_data(list,i); - if(data->cpu_id == tmp_raw_trace_data->cpu_id){ - data->pid = out; - } - } - } - } - - ltt_event_position(e, tmp_raw_trace_data->ep); - - if(event_viewer_data->raw_trace_data_queue_tmp->length >= RESERVE_SMALL_SIZE){ - if(event_viewer_data->append){ - list = g_list_last(event_viewer_data->raw_trace_data_queue_tmp->head); - data = (RawTraceData *)(list->data); - if(data->time.tv_sec == time.tv_sec && - data->time.tv_nsec == time.tv_nsec){ - g_queue_push_tail(event_viewer_data->raw_trace_data_queue_tmp,tmp_raw_trace_data); - }else{ - g_free(tmp_raw_trace_data); - } - }else{ - remove_item_from_queue(event_viewer_data->raw_trace_data_queue_tmp,TRUE); - g_queue_push_tail(event_viewer_data->raw_trace_data_queue_tmp,tmp_raw_trace_data); - } - }else{ - g_queue_push_tail (event_viewer_data->raw_trace_data_queue_tmp,tmp_raw_trace_data); - } - - g_string_free(detail_event, TRUE); - - return FALSE; -} - -void remove_item_from_queue(GQueue * q, gboolean fromHead) -{ - RawTraceData *data1, *data2 = NULL; - GList * list; - - if(fromHead){ - data1 = (RawTraceData *)g_queue_pop_head(q); - list = g_list_first(q->head); - if(list) - data2 = (RawTraceData *)(list->data); - }else{ - data1 = (RawTraceData *)g_queue_pop_tail(q); - list = g_list_last(q->head); - if(list) - data2 = (RawTraceData *)(list->data); - } - - if(data2){ - if(data1->time.tv_sec == data2->time.tv_sec && - data1->time.tv_nsec == data2->time.tv_nsec){ - remove_item_from_queue(q, fromHead); - } - } - - g_free(data1); - - return; -} - -void remove_all_items_from_queue(GQueue *q) -{ - RawTraceData *data; - while((data = (RawTraceData *)g_queue_pop_head(q)) != NULL){ - g_free(data); - } -} - - diff --git a/ltt/branches/poly/lttv/modules/guiStatistic/Makefile.am b/ltt/branches/poly/lttv/modules/guiStatistic/Makefile.am deleted file mode 100644 index 0794479d..00000000 --- a/ltt/branches/poly/lttv/modules/guiStatistic/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -# -# 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/API -lmainWinApi - -libdir = ${lttvplugindir} - -lib_LTLIBRARIES = libguiStatistic.la -libguiStatistic_la_LDFLAGS = -module -libguiStatistic_la_SOURCES = guiStatistic.c diff --git a/ltt/branches/poly/lttv/modules/guiStatistic/guiStatistic.c b/ltt/branches/poly/lttv/modules/guiStatistic/guiStatistic.c deleted file mode 100644 index aef524e5..00000000 --- a/ltt/branches/poly/lttv/modules/guiStatistic/guiStatistic.c +++ /dev/null @@ -1,687 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include "../icons/hGuiStatisticInsert.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) - -#define PATH_LENGTH 256 - -static LttvModule *statistic_main_win_module; -static GPtrArray * statistic_traceset; - -/** Array containing instanced objects. Used when module is unloaded */ -static GSList *g_statistic_viewer_data_list = NULL ; - -typedef struct _StatisticViewerData StatisticViewerData; - -//! Statistic Viewer's constructor hook -GtkWidget *h_gui_statistic(MainWindow *parent_window, LttvTracesetSelector * s, char* key); -//! Statistic Viewer's constructor -StatisticViewerData *gui_statistic(MainWindow *parent_window,LttvTracesetSelector * s, char* key); -//! Statistic Viewer's destructor -void gui_statistic_destructor(StatisticViewerData *statistic_viewer_data); -void gui_statistic_free(StatisticViewerData *statistic_viewer_data); - -void grab_focus(GtkWidget *widget, gpointer data); -static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data); - -void statistic_destroy_hash_key(gpointer key); -void statistic_destroy_hash_data(gpointer data); - -void show_traceset_stats(StatisticViewerData * statistic_viewer_data); -void show_tree(StatisticViewerData * statistic_viewer_data, - LttvAttribute* stats, GtkTreeIter* parent); -void show_statistic(StatisticViewerData * statistic_viewer_data, - LttvAttribute* stats, GtkTextBuffer* buf); - - -/** hook functions for update time interval, current time ... */ -gboolean statistic_update_time_window(void * hook_data, void * call_data); -gboolean statistic_show_viewer(void * hook_data, void * call_data); -gboolean statistic_traceset_changed(void * hook_data, void * call_data); -void statistic_add_context_hooks(StatisticViewerData * statistic_viewer_data, - LttvTracesetContext * tsc); -void statistic_remove_context_hooks(StatisticViewerData * statistic_viewer_data, - LttvTracesetContext * tsc); - -gboolean statistic_insert_traceset_stats(void * stats); - -enum -{ - NAME_COLUMN, - N_COLUMNS -}; - -struct _StatisticViewerData{ - MainWindow * mw; - LttvTracesetStats * stats; - gboolean calculate_stats; - int size; - - TimeInterval time_span; - gboolean shown; //indicate if the statistic is shown or not - char * filter_key; - - GtkWidget * hpaned_v; - GtkTreeStore * store_m; - GtkWidget * tree_v; - - //scroll window containing Tree View - GtkWidget * scroll_win_tree; - - GtkWidget * text_v; - //scroll window containing Text View - GtkWidget * scroll_win_text; - - // Selection handler - GtkTreeSelection *select_c; - - //hash - GHashTable *statistic_hash; -}; - - -/** - * plugin's init function - * - * This function initializes the Statistic Viewer functionnality through the - * gtkTraceSet API. - */ -G_MODULE_EXPORT void init(LttvModule *self, int argc, char *argv[]) { - - statistic_main_win_module = lttv_module_require(self, "mainwin", argc, argv); - - if(statistic_main_win_module == NULL){ - g_critical("Can't load Statistic Viewer : missing mainwin\n"); - return; - } - - statistic_traceset = g_ptr_array_new (); - - /* Register the toolbar insert button */ - toolbar_item_reg(hGuiStatisticInsert_xpm, "Insert Statistic Viewer", h_gui_statistic); - - /* Register the menu item insert entry */ - menu_item_reg("/", "Insert Statistic Viewer", h_gui_statistic); - -} - -void statistic_destroy_walk(gpointer data, gpointer user_data) -{ - gui_statistic_destructor((StatisticViewerData*)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. - */ -G_MODULE_EXPORT void destroy() { - int i; - - if(g_statistic_viewer_data_list){ - g_slist_foreach(g_statistic_viewer_data_list, statistic_destroy_walk, NULL ); - g_slist_free(g_statistic_viewer_data_list); - } - g_ptr_array_free (statistic_traceset, TRUE); - - /* Unregister the toolbar insert button */ - toolbar_item_unreg(h_gui_statistic); - - /* Unregister the menu item insert entry */ - menu_item_unreg(h_gui_statistic); -} - - -void -gui_statistic_free(StatisticViewerData *statistic_viewer_data) -{ - if(statistic_viewer_data){ - unreg_update_time_window(statistic_update_time_window,statistic_viewer_data, statistic_viewer_data->mw); - unreg_show_viewer(statistic_show_viewer,statistic_viewer_data, statistic_viewer_data->mw); - unreg_update_traceset(statistic_traceset_changed,statistic_viewer_data, statistic_viewer_data->mw); - - g_hash_table_destroy(statistic_viewer_data->statistic_hash); - g_free(statistic_viewer_data->filter_key); - g_statistic_viewer_data_list = g_slist_remove(g_statistic_viewer_data_list, statistic_viewer_data); - g_free(statistic_viewer_data); - } -} - -void -gui_statistic_destructor(StatisticViewerData *statistic_viewer_data) -{ - /* May already been done by GTK window closing */ - if(GTK_IS_WIDGET(statistic_viewer_data->hpaned_v)){ - gtk_widget_destroy(statistic_viewer_data->hpaned_v); - statistic_viewer_data = NULL; - } - //gui_statistic_free(statistic_viewer_data); -} - - -/** - * Statistic Viewer's constructor hook - * - * This constructor is given as a parameter to the menuitem and toolbar button - * registration. It creates the list. - * @param parent_window A pointer to the parent window. - * @return The widget created. - */ -GtkWidget * -h_gui_statistic(MainWindow * parent_window, LttvTracesetSelector * s, char* key) -{ - StatisticViewerData* statistic_viewer_data = gui_statistic(parent_window, s, key) ; - - if(statistic_viewer_data) - return statistic_viewer_data->hpaned_v; - else return NULL; - -} - -gboolean statistic_insert_traceset_stats(void * stats) -{ - int i, len; - gpointer s; - - len = statistic_traceset->len; - for(i=0;imw = parent_window; - statistic_viewer_data->stats = get_traceset_stats_api(statistic_viewer_data->mw); - statistic_viewer_data->calculate_stats = statistic_insert_traceset_stats((void *)statistic_viewer_data->stats); - - reg_update_time_window(statistic_update_time_window,statistic_viewer_data, statistic_viewer_data->mw); - reg_show_viewer(statistic_show_viewer,statistic_viewer_data, statistic_viewer_data->mw); - reg_update_traceset(statistic_traceset_changed,statistic_viewer_data, statistic_viewer_data->mw); - - statistic_viewer_data->statistic_hash = g_hash_table_new_full(g_str_hash, g_str_equal, - statistic_destroy_hash_key, - statistic_destroy_hash_data); - - statistic_viewer_data->hpaned_v = gtk_hpaned_new(); - statistic_viewer_data->store_m = gtk_tree_store_new (N_COLUMNS, G_TYPE_STRING); - statistic_viewer_data->tree_v = gtk_tree_view_new_with_model (GTK_TREE_MODEL (statistic_viewer_data->store_m)); - g_object_unref (G_OBJECT (statistic_viewer_data->store_m)); - - g_signal_connect (G_OBJECT (statistic_viewer_data->tree_v), "grab-focus", - G_CALLBACK (grab_focus), - statistic_viewer_data); - - // Setup the selection handler - statistic_viewer_data->select_c = gtk_tree_view_get_selection (GTK_TREE_VIEW (statistic_viewer_data->tree_v)); - gtk_tree_selection_set_mode (statistic_viewer_data->select_c, GTK_SELECTION_SINGLE); - g_signal_connect (G_OBJECT (statistic_viewer_data->select_c), "changed", - G_CALLBACK (tree_selection_changed_cb), - statistic_viewer_data); - - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("Statistic Name", - renderer, - "text", NAME_COLUMN, - NULL); - gtk_tree_view_column_set_alignment (column, 0.0); - // gtk_tree_view_column_set_fixed_width (column, 45); - gtk_tree_view_append_column (GTK_TREE_VIEW (statistic_viewer_data->tree_v), column); - - - gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (statistic_viewer_data->tree_v), FALSE); - - statistic_viewer_data->scroll_win_tree = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(statistic_viewer_data->scroll_win_tree), - GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC); - - gtk_container_add (GTK_CONTAINER (statistic_viewer_data->scroll_win_tree), statistic_viewer_data->tree_v); - gtk_paned_pack1(GTK_PANED(statistic_viewer_data->hpaned_v),statistic_viewer_data->scroll_win_tree, TRUE, FALSE); - gtk_paned_set_position(GTK_PANED(statistic_viewer_data->hpaned_v), 160); - - statistic_viewer_data->scroll_win_text = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(statistic_viewer_data->scroll_win_text), - GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC); - - statistic_viewer_data->text_v = gtk_text_view_new (); - g_signal_connect (G_OBJECT (statistic_viewer_data->text_v), "grab-focus", - G_CALLBACK (grab_focus), - statistic_viewer_data); - - gtk_text_view_set_editable(GTK_TEXT_VIEW(statistic_viewer_data->text_v),FALSE); - gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(statistic_viewer_data->text_v),FALSE); - gtk_container_add (GTK_CONTAINER (statistic_viewer_data->scroll_win_text), statistic_viewer_data->text_v); - gtk_paned_pack2(GTK_PANED(statistic_viewer_data->hpaned_v), statistic_viewer_data->scroll_win_text, TRUE, FALSE); - - gtk_widget_show(statistic_viewer_data->scroll_win_tree); - gtk_widget_show(statistic_viewer_data->scroll_win_text); - gtk_widget_show(statistic_viewer_data->tree_v); - gtk_widget_show(statistic_viewer_data->text_v); - gtk_widget_show(statistic_viewer_data->hpaned_v); - - //get the life span of the traceset and set the upper of the scroll bar - get_traceset_time_span(statistic_viewer_data->mw, &statistic_viewer_data->time_span); - - statistic_viewer_data->shown = FALSE; - statistic_viewer_data->filter_key = g_strdup(key); - g_object_set_data( - G_OBJECT(statistic_viewer_data->hpaned_v), - statistic_viewer_data->filter_key, - s); - - g_object_set_data( - G_OBJECT(statistic_viewer_data->hpaned_v), - TRACESET_TIME_SPAN, - &statistic_viewer_data->time_span); - - if(statistic_viewer_data->calculate_stats){ - if(lttv_stats_load_statistics(statistic_viewer_data->stats)) - statistic_viewer_data->calculate_stats = FALSE; - } - - if(statistic_viewer_data->calculate_stats == FALSE){ - statistic_viewer_data->size = 1; - g_object_set_data( - G_OBJECT(statistic_viewer_data->hpaned_v), - MAX_NUMBER_EVENT, - &statistic_viewer_data->size); - } - - g_object_set_data_full( - G_OBJECT(statistic_viewer_data->hpaned_v), - "statistic_viewer_data", - statistic_viewer_data, - (GDestroyNotify)gui_statistic_free); - - /* Add the object's information to the module's array */ - g_statistic_viewer_data_list = g_slist_append( - g_statistic_viewer_data_list, - statistic_viewer_data); - - return statistic_viewer_data; -} - -void grab_focus(GtkWidget *widget, gpointer data) -{ - StatisticViewerData *statistic_viewer_data = (StatisticViewerData *)data; - MainWindow * mw = statistic_viewer_data->mw; - set_focused_pane(mw, gtk_widget_get_parent(statistic_viewer_data->hpaned_v)); -} - -static void -tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data) -{ - StatisticViewerData *statistic_viewer_data = (StatisticViewerData*)data; - GtkTreeIter iter; - GtkTreeModel *model = GTK_TREE_MODEL(statistic_viewer_data->store_m); - gchar *event; - GtkTextBuffer* buf; - gchar * str; - GtkTreePath * path; - GtkTextIter text_iter; - LttvAttribute * stats; - - if (gtk_tree_selection_get_selected (selection, &model, &iter)) - { - gtk_tree_model_get (model, &iter, NAME_COLUMN, &event, -1); - - path = gtk_tree_model_get_path(GTK_TREE_MODEL(model),&iter); - str = gtk_tree_path_to_string (path); - stats = (LttvAttribute*)g_hash_table_lookup (statistic_viewer_data->statistic_hash,str); - g_free(str); - - buf = gtk_text_view_get_buffer((GtkTextView*)statistic_viewer_data->text_v); - gtk_text_buffer_set_text(buf,"Statistic for '", -1); - gtk_text_buffer_get_end_iter(buf, &text_iter); - gtk_text_buffer_insert(buf, &text_iter, event, strlen(event)); - gtk_text_buffer_get_end_iter(buf, &text_iter); - gtk_text_buffer_insert(buf, &text_iter, "' :\n\n",5); - - show_statistic(statistic_viewer_data, stats, buf); - - g_free (event); - } -} - -void statistic_destroy_hash_key(gpointer key) -{ - g_free(key); -} - -void statistic_destroy_hash_data(gpointer data) -{ - // g_free(data); -} - -void show_traceset_stats(StatisticViewerData * statistic_viewer_data) -{ - int i, nb; - LttvTraceset *ts; - LttvTraceStats *tcs; - LttSystemDescription *desc; - LttvTracesetStats * tscs = statistic_viewer_data->stats; - gchar * str, trace_str[PATH_LENGTH]; - GtkTreePath * path; - GtkTreeIter iter; - GtkTreeStore * store = statistic_viewer_data->store_m; - - if(tscs->stats == NULL) return; - - gtk_tree_store_append (store, &iter, NULL); - gtk_tree_store_set (store, &iter, - NAME_COLUMN, "Traceset statistics", - -1); - path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter); - str = gtk_tree_path_to_string (path); - g_hash_table_insert(statistic_viewer_data->statistic_hash, - (gpointer)str, tscs->stats); - show_tree(statistic_viewer_data, tscs->stats, &iter); - - //show stats for all traces - ts = tscs->parent.parent.ts; - nb = lttv_traceset_number(ts); - - for(i = 0 ; i < nb ; i++) { - tcs = (LttvTraceStats *)(LTTV_TRACESET_CONTEXT(tscs)->traces[i]); - desc = ltt_trace_system_description(tcs->parent.parent.t); - sprintf(trace_str, "Trace on system %s at time %d secs", - ltt_trace_system_description_node_name(desc), - (ltt_trace_system_description_trace_start_time(desc)).tv_sec); - - gtk_tree_store_append (store, &iter, NULL); - gtk_tree_store_set (store, &iter,NAME_COLUMN,trace_str,-1); - path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter); - str = gtk_tree_path_to_string (path); - g_hash_table_insert(statistic_viewer_data->statistic_hash, - (gpointer)str,tcs->stats); - show_tree(statistic_viewer_data, tcs->stats, &iter); - } -} - -void show_tree(StatisticViewerData * statistic_viewer_data, - LttvAttribute* stats, GtkTreeIter* parent) -{ - int i, nb; - LttvAttribute *subtree; - LttvAttributeName name; - LttvAttributeValue value; - LttvAttributeType type; - gchar * str, dir_str[PATH_LENGTH]; - GtkTreePath * path; - GtkTreeIter iter; - GtkTreeStore * store = statistic_viewer_data->store_m; - - nb = lttv_attribute_get_number(stats); - for(i = 0 ; i < nb ; i++) { - type = lttv_attribute_get(stats, i, &name, &value); - switch(type) { - case LTTV_GOBJECT: - if(LTTV_IS_ATTRIBUTE(*(value.v_gobject))) { - sprintf(dir_str, "%s", g_quark_to_string(name)); - subtree = (LttvAttribute *)*(value.v_gobject); - gtk_tree_store_append (store, &iter, parent); - gtk_tree_store_set (store, &iter,NAME_COLUMN,dir_str,-1); - path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter); - str = gtk_tree_path_to_string (path); - g_hash_table_insert(statistic_viewer_data->statistic_hash, - (gpointer)str, subtree); - show_tree(statistic_viewer_data, subtree, &iter); - } - break; - default: - break; - } - } -} - -void show_statistic(StatisticViewerData * statistic_viewer_data, - LttvAttribute* stats, GtkTextBuffer* buf) -{ - int i, nb , flag; - LttvAttribute *subtree; - LttvAttributeName name; - LttvAttributeValue value; - LttvAttributeType type; - gchar type_name[PATH_LENGTH], type_value[PATH_LENGTH]; - GtkTextIter text_iter; - - flag = 0; - nb = lttv_attribute_get_number(stats); - for(i = 0 ; i < nb ; i++) { - type = lttv_attribute_get(stats, i, &name, &value); - sprintf(type_name,"%s", g_quark_to_string(name)); - type_value[0] = '\0'; - switch(type) { - case LTTV_INT: - sprintf(type_value, " : %d\n", *value.v_int); - break; - case LTTV_UINT: - sprintf(type_value, " : %u\n", *value.v_uint); - break; - case LTTV_LONG: - sprintf(type_value, " : %ld\n", *value.v_long); - break; - case LTTV_ULONG: - sprintf(type_value, " : %lu\n", *value.v_ulong); - break; - case LTTV_FLOAT: - sprintf(type_value, " : %f\n", (double)*value.v_float); - break; - case LTTV_DOUBLE: - sprintf(type_value, " : %f\n", *value.v_double); - break; - case LTTV_TIME: - sprintf(type_value, " : %10u.%09u\n", value.v_time->tv_sec, - value.v_time->tv_nsec); - break; - case LTTV_POINTER: - sprintf(type_value, " : POINTER\n"); - break; - case LTTV_STRING: - sprintf(type_value, " : %s\n", *value.v_string); - break; - default: - break; - } - if(strlen(type_value)){ - flag = 1; - strcat(type_name,type_value); - gtk_text_buffer_get_end_iter(buf, &text_iter); - gtk_text_buffer_insert(buf, &text_iter, type_name, strlen(type_name)); - } - } - - if(flag == 0){ - sprintf(type_value, "No statistic information in this directory.\nCheck in subdirectories please.\n"); - gtk_text_buffer_get_end_iter(buf, &text_iter); - gtk_text_buffer_insert(buf, &text_iter, type_value, strlen(type_value)); - - } -} - -gboolean statistic_update_time_window(void * hook_data, void * call_data) -{ - StatisticViewerData *statistic_viewer_data = (StatisticViewerData*) hook_data; - LttvTracesetContext * tsc = get_traceset_context(statistic_viewer_data->mw); - - //if statistic is already calculated, do nothing - if(!statistic_viewer_data->calculate_stats){ - return FALSE; - } - - if(statistic_viewer_data->shown == FALSE){ - statistic_add_context_hooks(statistic_viewer_data, tsc); - } - return FALSE; -} - -gboolean statistic_show_viewer(void * hook_data, void * call_data) -{ - StatisticViewerData *statistic_viewer_data = (StatisticViewerData*) hook_data; - LttvTracesetContext * tsc = get_traceset_context(statistic_viewer_data->mw); - - if(statistic_viewer_data->shown == FALSE){ - statistic_viewer_data->shown = TRUE; - show_traceset_stats(statistic_viewer_data); - if(statistic_viewer_data->calculate_stats){ - statistic_remove_context_hooks(statistic_viewer_data,tsc); - lttv_stats_save_statistics((LttvTracesetStats*)tsc); - } - } - - return FALSE; -} - -gboolean statistic_traceset_changed(void * hook_data, void * call_data) -{ - StatisticViewerData *statistic_viewer_data = (StatisticViewerData*) hook_data; - - // gtk_tree_store_clear (statistic_viewer_data->store_m); - // statistic_viewer_data->shown = FALSE; - - return FALSE; -} - -void statistic_add_context_hooks(StatisticViewerData * statistic_viewer_data, - LttvTracesetContext * tsc) -{ - gint i, j, nbi, nb_tracefile, nb_control, nb_per_cpu; - LttTrace *trace; - LttvTraceContext *tc; - LttvTracefileContext *tfc; - LttvTracesetSelector * ts_s; - LttvTraceSelector * t_s; - LttvTracefileSelector * tf_s; - gboolean selected; - - ts_s = (LttvTracesetSelector*)g_object_get_data(G_OBJECT(statistic_viewer_data->hpaned_v), - statistic_viewer_data->filter_key); - - //if there are hooks for traceset, add them here - - nbi = lttv_traceset_number(tsc->ts); - for(i = 0 ; i < nbi ; i++) { - t_s = lttv_traceset_selector_trace_get(ts_s,i); - selected = lttv_trace_selector_get_selected(t_s); - if(!selected) continue; - tc = tsc->traces[i]; - trace = tc->t; - //if there are hooks for trace, add them here - - nb_control = ltt_trace_control_tracefile_number(trace); - nb_per_cpu = ltt_trace_per_cpu_tracefile_number(trace); - nb_tracefile = nb_control + nb_per_cpu; - - for(j = 0 ; j < nb_tracefile ; j++) { - tf_s = lttv_trace_selector_tracefile_get(t_s,j); - selected = lttv_tracefile_selector_get_selected(tf_s); - if(!selected) continue; - - if(j < nb_control) - tfc = tc->control_tracefiles[j]; - else - tfc = tc->per_cpu_tracefiles[j - nb_control]; - - //if there are hooks for tracefile, add them here - // lttv_tracefile_context_add_hooks(tfc, NULL,NULL,NULL,NULL, - // statistic_viewer_data->before_event_hooks,NULL); - } - } - - //add state and stats hooks - //state_add_event_hooks_api(statistic_viewer_data->mw); //it will be added in the main window - stats_add_event_hooks_api(statistic_viewer_data->mw); - -} - -void statistic_remove_context_hooks(StatisticViewerData * statistic_viewer_data, - LttvTracesetContext * tsc) -{ - gint i, j, nbi, nb_tracefile, nb_control, nb_per_cpu; - LttTrace *trace; - LttvTraceContext *tc; - LttvTracefileContext *tfc; - LttvTracesetSelector * ts_s; - LttvTraceSelector * t_s; - LttvTracefileSelector * tf_s; - gboolean selected; - - ts_s = (LttvTracesetSelector*)g_object_get_data(G_OBJECT(statistic_viewer_data->hpaned_v), - statistic_viewer_data->filter_key); - - //if there are hooks for traceset, remove them here - - nbi = lttv_traceset_number(tsc->ts); - for(i = 0 ; i < nbi ; i++) { - t_s = lttv_traceset_selector_trace_get(ts_s,i); - selected = lttv_trace_selector_get_selected(t_s); - if(!selected) continue; - tc = tsc->traces[i]; - trace = tc->t; - //if there are hooks for trace, remove them here - - nb_control = ltt_trace_control_tracefile_number(trace); - nb_per_cpu = ltt_trace_per_cpu_tracefile_number(trace); - nb_tracefile = nb_control + nb_per_cpu; - - for(j = 0 ; j < nb_tracefile ; j++) { - tf_s = lttv_trace_selector_tracefile_get(t_s,j); - selected = lttv_tracefile_selector_get_selected(tf_s); - if(!selected) continue; - - if(j < nb_control) - tfc = tc->control_tracefiles[j]; - else - tfc = tc->per_cpu_tracefiles[j - nb_control]; - - //if there are hooks for tracefile, remove them here - // lttv_tracefile_context_remove_hooks(tfc, NULL,NULL,NULL,NULL, - // statistic_viewer_data->before_event_hooks,NULL); - } - } - - //remove state and stats hooks - //state_remove_event_hooks_api(statistic_viewer_data->mw); //it will be done in the main window - stats_remove_event_hooks_api(statistic_viewer_data->mw); -} - -