From e800cf849a08893a7325441a9614f018a00b129a Mon Sep 17 00:00:00 2001 From: compudj Date: Sun, 8 Aug 2004 01:12:12 +0000 Subject: [PATCH] whole new time bar, plus some additions to control flow viewer.. this is work in progress git-svn-id: http://ltt.polymtl.ca/svn@671 04897980-b3bd-0310-b5e0-8ef037075253 --- .../modules/gui/controlflow/cfv-private.h | 2 + .../poly/lttv/modules/gui/controlflow/cfv.c | 1 + .../lttv/modules/gui/controlflow/drawing.c | 41 +- .../lttv/modules/gui/controlflow/drawing.h | 12 + .../lttv/modules/gui/controlflow/drawitem.c | 346 +++++---- .../lttv/modules/gui/controlflow/drawitem.h | 99 ++- .../lttv/modules/gui/controlflow/eventhooks.c | 716 +++++++++--------- .../modules/gui/controlflow/processlist.c | 39 +- .../lttv/modules/gui/detailedevents/events.c | 2 +- .../gui/lttvwindow/lttvwindow/callbacks.c | 535 ++++++++++++- .../gui/lttvwindow/lttvwindow/callbacks.h | 27 + .../gui/lttvwindow/lttvwindow/interface.c | 14 +- .../gui/lttvwindow/lttvwindow/lttvwindow.c | 14 +- .../gui/lttvwindow/lttvwindow/lttvwindow.h | 8 +- .../lttvwindow/mainwindow-private.h | 21 + .../gui/lttvwindow/pixmaps/Makefile.am | 3 +- .../lttvwindow/pixmaps/stock_jump_to_24.png | Bin 0 -> 1097 bytes 17 files changed, 1251 insertions(+), 629 deletions(-) create mode 100644 ltt/branches/poly/lttv/modules/gui/lttvwindow/pixmaps/stock_jump_to_24.png diff --git a/ltt/branches/poly/lttv/modules/gui/controlflow/cfv-private.h b/ltt/branches/poly/lttv/modules/gui/controlflow/cfv-private.h index d9b1596c..0c4f63d6 100644 --- a/ltt/branches/poly/lttv/modules/gui/controlflow/cfv-private.h +++ b/ltt/branches/poly/lttv/modules/gui/controlflow/cfv-private.h @@ -39,6 +39,8 @@ struct _ControlFlowData { //guint currently_Selected_Event ; guint number_of_process; + guint background_info_waiting; /* Number of background requests waited for + in order to have all the info ready. */ } ; diff --git a/ltt/branches/poly/lttv/modules/gui/controlflow/cfv.c b/ltt/branches/poly/lttv/modules/gui/controlflow/cfv.c index 276e40ae..ba53e288 100644 --- a/ltt/branches/poly/lttv/modules/gui/controlflow/cfv.c +++ b/ltt/branches/poly/lttv/modules/gui/controlflow/cfv.c @@ -91,6 +91,7 @@ guicontrolflow(void) drawing_get_drawing_area(control_flow_data->drawing); control_flow_data->number_of_process = 0; + control_flow_data->background_info_waiting = 0; /* Create the Process list */ control_flow_data->process_list = processlist_construct(); diff --git a/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c b/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c index 2cd92c2e..8ef1b430 100644 --- a/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c +++ b/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c @@ -33,6 +33,20 @@ #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) + +GdkColor drawing_colors[NUM_COLORS] = +{ /* Pixel, R, G, B */ + { 0, 0, 0, 0 }, /* COL_BLACK */ + { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_WHITE */ + { 0, 0x0fff, 0xffff, 0xfff0 }, /* COL_WAIT_FORK */ + { 0, 0xffff, 0xffff, 0x0000 }, /* COL_WAIT_CPU */ + { 0, 0xffff, 0x0000, 0xffff }, /* COL_EXIT */ + { 0, 0xffff, 0x0000, 0x0000 }, /* COL_WAIT */ + { 0, 0x0000, 0xffff, 0x0000 } /* COL_RUN */ +}; + + + /***************************************************************************** * drawing functions * *****************************************************************************/ @@ -44,28 +58,6 @@ static gboolean motion_notify_ruler(GtkWidget *widget, GdkEventMotion *event, gpointer user_data); -//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 do an events request to the lttvwindow API to ask for this update. * Note : this function cannot clear the background, because it may @@ -234,7 +226,8 @@ void drawing_chunk_begin(EventsRequest *events_request, LttvTracesetState *tss) LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tss); LttTime current_time = lttv_traceset_context_get_current_tfc(tsc)->timestamp; - cfd->drawing->last_start = current_time; + cfd->drawing->last_start = LTT_TIME_MIN(current_time, + events_request->end_time); } @@ -490,7 +483,7 @@ button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer user_data window_end, &time); - lttvwindow_report_current_time(control_flow_data->tab, &time); + lttvwindow_report_current_time(control_flow_data->tab, time); } diff --git a/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.h b/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.h index 1139d48b..19da1678 100644 --- a/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.h +++ b/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.h @@ -33,6 +33,18 @@ #define SAFETY 50 // safety pixels at right and bottom of pixmap buffer + +typedef enum _draw_color { COL_BLACK, + COL_WHITE, + COL_WAIT_FORK, + COL_WAIT_CPU, + COL_EXIT, + COL_WAIT, + COL_RUN, + NUM_COLORS } draw_color; + +extern GdkColor drawing_colors[NUM_COLORS]; + /* This part of the viewer does : * Draw horizontal lines, getting graphic context as arg. * Copy region of the screen into another. diff --git a/ltt/branches/poly/lttv/modules/gui/controlflow/drawitem.c b/ltt/branches/poly/lttv/modules/gui/controlflow/drawitem.c index 2c72660a..a73df51a 100644 --- a/ltt/branches/poly/lttv/modules/gui/controlflow/drawitem.c +++ b/ltt/branches/poly/lttv/modules/gui/controlflow/drawitem.c @@ -113,7 +113,7 @@ /* drawing hook functions */ gboolean draw_text( void *hook_data, void *call_data) { - PropertiesText *Properties = (PropertiesText*)hook_data; + PropertiesText *properties = (PropertiesText*)hook_data; DrawContext *draw_context = (DrawContext*)call_data; PangoContext *context; @@ -128,39 +128,77 @@ gboolean draw_text( void *hook_data, void *call_data) context = pango_layout_get_context(layout); font_desc = pango_context_get_font_description(context); - pango_font_description_set_size(font_desc, Properties->size*PANGO_SCALE); + pango_font_description_set_size(font_desc, properties->size*PANGO_SCALE); pango_layout_context_changed(layout); - pango_layout_set_text(layout, Properties->text, -1); + pango_layout_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->drawinfo.modify_over.x, - draw_context->drawinfo.modify_over.y, - layout, Properties->foreground, Properties->background); - draw_context->drawinfo.modify_over.x += ink_rect.width; + gint x=0, y=0; + gint *offset=NULL; + gboolean enough_space = FALSE; + gint width = ink_rect.width; + + switch(properties->position.x) { + case POS_START: + x = draw_context->drawinfo.start.x; + switch(properties->position.y) { + case OVER: + offset = &draw_context->drawinfo.start.offset.over; + x += draw_context->drawinfo.start.offset.over; + y = draw_context->drawinfo.y.over; + break; + case MIDDLE: + offset = &draw_context->drawinfo.start.offset.middle; + x += draw_context->drawinfo.start.offset.middle; + y = draw_context->drawinfo.y.middle; + break; + case UNDER: + offset = &draw_context->drawinfo.start.offset.under; + x += draw_context->drawinfo.start.offset.under; + y = draw_context->drawinfo.y.under; + break; + } + /* verify if there is enough space to draw */ + if(x + width <= draw_context->drawinfo.end.x) { + enough_space = TRUE; + *offset += width; + } break; - case MIDDLE: - gdk_draw_layout_with_colors(draw_context->drawable, - draw_context->gc, - draw_context->drawinfo.modify_middle.x, - draw_context->drawinfo.modify_middle.y, - layout, Properties->foreground, Properties->background); - draw_context->drawinfo.modify_middle.x += ink_rect.width; - break; - case UNDER: - gdk_draw_layout_with_colors(draw_context->drawable, - draw_context->gc, - draw_context->drawinfo.modify_under.x, - draw_context->drawinfo.modify_under.y, - layout, Properties->foreground, Properties->background); - draw_context->drawinfo.modify_under.x += ink_rect.width; + case POS_END: + x = draw_context->drawinfo.end.x; + switch(properties->position.y) { + case OVER: + offset = &draw_context->drawinfo.end.offset.over; + x += draw_context->drawinfo.end.offset.over; + y = draw_context->drawinfo.y.over; + break; + case MIDDLE: + offset = &draw_context->drawinfo.end.offset.middle; + x += draw_context->drawinfo.end.offset.middle; + y = draw_context->drawinfo.y.middle; + break; + case UNDER: + offset = &draw_context->drawinfo.end.offset.under; + x += draw_context->drawinfo.end.offset.under; + y = draw_context->drawinfo.y.under; + break; + } + /* verify if there is enough space to draw */ + if(x - width >= draw_context->drawinfo.start.x) { + enough_space = TRUE; + *offset -= width; + } break; } + if(enough_space) + gdk_draw_layout_with_colors(draw_context->drawable, + draw_context->gc, + x, + y, + layout, properties->foreground, properties->background); + return 0; } @@ -194,60 +232,82 @@ gboolean draw_icon( void *hook_data, void *call_data) icon_info = *(value.v_pointer); } - gdk_gc_set_clip_mask(draw_context->gc, icon_info->mask); + gint x=0, y=0; + gint *offset=NULL; + gboolean enough_space = FALSE; + gint width = properties->width; - switch(properties->position) { - case OVER: - gdk_gc_set_clip_origin( - draw_context->gc, - draw_context->drawinfo.modify_over.x, - draw_context->drawinfo.modify_over.y); - gdk_draw_drawable(draw_context->drawable, - draw_context->gc, - icon_info->pixmap, - 0, 0, - draw_context->drawinfo.modify_over.x, - draw_context->drawinfo.modify_over.y, - properties->width, properties->height); - - draw_context->drawinfo.modify_over.x += properties->width; - - break; - case MIDDLE: - gdk_gc_set_clip_origin( - draw_context->gc, - draw_context->drawinfo.modify_middle.x, - draw_context->drawinfo.modify_middle.y); - gdk_draw_drawable(draw_context->drawable, - draw_context->gc, - icon_info->pixmap, - 0, 0, - draw_context->drawinfo.modify_middle.x, - draw_context->drawinfo.modify_middle.y, - properties->width, properties->height); - - draw_context->drawinfo.modify_middle.x += properties->width; + switch(properties->position.x) { + case POS_START: + x = draw_context->drawinfo.start.x; + switch(properties->position.y) { + case OVER: + offset = &draw_context->drawinfo.start.offset.over; + x += draw_context->drawinfo.start.offset.over; + y = draw_context->drawinfo.y.over; + break; + case MIDDLE: + offset = &draw_context->drawinfo.start.offset.middle; + x += draw_context->drawinfo.start.offset.middle; + y = draw_context->drawinfo.y.middle; + break; + case UNDER: + offset = &draw_context->drawinfo.start.offset.under; + x += draw_context->drawinfo.start.offset.under; + y = draw_context->drawinfo.y.under; + break; + } + /* verify if there is enough space to draw */ + if(x + width <= draw_context->drawinfo.end.x) { + enough_space = TRUE; + *offset += width; + } break; - case UNDER: - gdk_gc_set_clip_origin( - draw_context->gc, - draw_context->drawinfo.modify_under.x, - draw_context->drawinfo.modify_under.y); - gdk_draw_drawable(draw_context->drawable, - draw_context->gc, - icon_info->pixmap, - 0, 0, - draw_context->drawinfo.modify_under.x, - draw_context->drawinfo.modify_under.y, - properties->width, properties->height); - - draw_context->drawinfo.modify_under.x += properties->width; + case POS_END: + x = draw_context->drawinfo.end.x; + switch(properties->position.y) { + case OVER: + offset = &draw_context->drawinfo.end.offset.over; + x += draw_context->drawinfo.end.offset.over; + y = draw_context->drawinfo.y.over; + break; + case MIDDLE: + offset = &draw_context->drawinfo.end.offset.middle; + x += draw_context->drawinfo.end.offset.middle; + y = draw_context->drawinfo.y.middle; + break; + case UNDER: + offset = &draw_context->drawinfo.end.offset.under; + x += draw_context->drawinfo.end.offset.under; + y = draw_context->drawinfo.y.under; + break; + } + /* verify if there is enough space to draw */ + if(x - width >= draw_context->drawinfo.start.x) { + enough_space = TRUE; + *offset -= width; + } break; } - gdk_gc_set_clip_origin(draw_context->gc, 0, 0); - gdk_gc_set_clip_mask(draw_context->gc, NULL); - + if(enough_space) { + gdk_gc_set_clip_mask(draw_context->gc, icon_info->mask); + + gdk_gc_set_clip_origin( + draw_context->gc, + x, + y); + gdk_draw_drawable(draw_context->drawable, + draw_context->gc, + icon_info->pixmap, + 0, 0, + x, + y, + properties->width, properties->height); + + gdk_gc_set_clip_origin(draw_context->gc, 0, 0); + gdk_gc_set_clip_mask(draw_context->gc, NULL); + } return 0; } @@ -255,7 +315,6 @@ 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); @@ -271,38 +330,30 @@ gboolean draw_line( void *hook_data, void *call_data) // draw_context->drawinfo.middle.x, // draw_context->drawinfo.middle.y); - switch(properties->position) { + gint x_begin=0, x_end=0, y=0; + + x_begin = draw_context->drawinfo.start.x; + x_end = draw_context->drawinfo.end.x; + + switch(properties->y) { case OVER: - drawing_draw_line( - NULL, draw_context->drawable, - draw_context->previous->over->x, - draw_context->previous->over->y, - draw_context->drawinfo.over.x, - draw_context->current->over->y, - draw_context->gc); + y = draw_context->drawinfo.y.over; break; case MIDDLE: - drawing_draw_line( - NULL, draw_context->drawable, - draw_context->previous->middle->x, - draw_context->previous->middle->y, - draw_context->drawinfo.middle.x, - draw_context->drawinfo.middle.y, - draw_context->gc); + y = draw_context->drawinfo.y.middle; break; case UNDER: - drawing_draw_line( - NULL, draw_context->drawable, - draw_context->previous->under->x, - draw_context->previous->under->y, - draw_context->drawinfo.under.x, - draw_context->drawinfo.under.y, - draw_context->gc); - + y = draw_context->drawinfo.y.under; break; } - - //gdk_gc_unref(gc); + + drawing_draw_line( + NULL, draw_context->drawable, + x_begin, + y, + x_end, + y, + draw_context->gc); return 0; } @@ -315,35 +366,70 @@ gboolean draw_arc( void *hook_data, void *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->drawinfo.modify_over.x, - draw_context->drawinfo.modify_over.y, - properties->size, properties->size, 0, 360*64); - draw_context->drawinfo.modify_over.x += properties->size; - break; - case MIDDLE: - gdk_draw_arc(draw_context->drawable, draw_context->gc, - properties->filled, - draw_context->drawinfo.modify_middle.x, - draw_context->drawinfo.modify_middle.y, - properties->size, properties->size, 0, 360*64); - draw_context->drawinfo.modify_middle.x += properties->size; - - break; - case UNDER: - gdk_draw_arc(draw_context->drawable, draw_context->gc, - properties->filled, - draw_context->drawinfo.modify_under.x, - draw_context->drawinfo.modify_under.y, - properties->size, properties->size, 0, 360*64); - draw_context->drawinfo.modify_under.x += properties->size; + gint x=0, y=0; + gint *offset=NULL; + gboolean enough_space = FALSE; + gint width = properties->size; + switch(properties->position.x) { + case POS_START: + x = draw_context->drawinfo.start.x; + switch(properties->position.y) { + case OVER: + offset = &draw_context->drawinfo.start.offset.over; + x += draw_context->drawinfo.start.offset.over; + y = draw_context->drawinfo.y.over; + break; + case MIDDLE: + offset = &draw_context->drawinfo.start.offset.middle; + x += draw_context->drawinfo.start.offset.middle; + y = draw_context->drawinfo.y.middle; + break; + case UNDER: + offset = &draw_context->drawinfo.start.offset.under; + x += draw_context->drawinfo.start.offset.under; + y = draw_context->drawinfo.y.under; + break; + } + /* verify if there is enough space to draw */ + if(x + width <= draw_context->drawinfo.end.x) { + enough_space = TRUE; + *offset += width; + } + break; + case POS_END: + x = draw_context->drawinfo.end.x; + switch(properties->position.y) { + case OVER: + offset = &draw_context->drawinfo.end.offset.over; + x += draw_context->drawinfo.end.offset.over; + y = draw_context->drawinfo.y.over; + break; + case MIDDLE: + offset = &draw_context->drawinfo.end.offset.middle; + x += draw_context->drawinfo.end.offset.middle; + y = draw_context->drawinfo.y.middle; + break; + case UNDER: + offset = &draw_context->drawinfo.end.offset.under; + x += draw_context->drawinfo.end.offset.under; + y = draw_context->drawinfo.y.under; + break; + } + /* verify if there is enough space to draw */ + if(x - width >= draw_context->drawinfo.start.x) { + enough_space = TRUE; + *offset -= width; + } break; } + if(enough_space) + gdk_draw_arc(draw_context->drawable, draw_context->gc, + properties->filled, + x, + y, + properties->size, properties->size, 0, 360*64); return 0; } @@ -365,10 +451,10 @@ gboolean draw_bg( void *hook_data, void *call_data) // draw_context->previous->over->x); gdk_draw_rectangle(draw_context->drawable, draw_context->gc, TRUE, - draw_context->previous->over->x, - draw_context->previous->over->y, - draw_context->drawinfo.over.x - draw_context->previous->over->x, - draw_context->previous->under->y-draw_context->previous->over->y); + draw_context->drawinfo.start.x, + draw_context->drawinfo.y.over, + draw_context->drawinfo.end.x - draw_context->drawinfo.start.x, + draw_context->drawinfo.y.under - draw_context->drawinfo.y.over); return 0; } diff --git a/ltt/branches/poly/lttv/modules/gui/controlflow/drawitem.h b/ltt/branches/poly/lttv/modules/gui/controlflow/drawitem.h index fe46c062..df945e3a 100644 --- a/ltt/branches/poly/lttv/modules/gui/controlflow/drawitem.h +++ b/ltt/branches/poly/lttv/modules/gui/controlflow/drawitem.h @@ -42,10 +42,13 @@ enum _DrawableItems { ITEM_TEXT, ITEM_ICON, ITEM_LINE, ITEM_POINT, ITEM_BACKGROUND }; +typedef enum _RelPosX { + POS_START, POS_END +} RelPosX; -typedef enum _RelPos { +typedef enum _RelPosY { OVER, MIDDLE, UNDER -} RelPos; +} RelPosY; /* The DrawContext keeps information about the current drawing position and @@ -70,16 +73,30 @@ struct _DrawContext { PangoLayout *pango_layout; struct { - gint x_start; - gint x_end; + struct { + gint x; + struct { + gint over; + gint middle; + gint under; + } offset; + } start; + + struct { + gint x; + struct { + gint over; + gint middle; + gint under; + } offset; + } end; + + struct { + gint over; + gint middle; + gint under; + } y; - gint y_over; - gint y_middle; - gint y_under; - - gint x_modify_over; - gint x_modify_middle; - gint x_modify_under; } drawinfo; }; @@ -132,9 +149,12 @@ static int Items_Priorities[] = { struct _PropertiesText { GdkColor *foreground; GdkColor *background; - gint size; - gchar *text; - RelPos position; + gint size; + gchar *text; + struct { + RelPosX x; + RelPosY y; + } position; }; @@ -142,21 +162,27 @@ struct _PropertiesIcon { gchar *icon_name; gint width; gint height; - RelPos position; + struct { + RelPosX x; + RelPosY y; + } position; }; struct _PropertiesLine { GdkColor color; gint line_width; GdkLineStyle style; - RelPos position; + RelPosY y; }; struct _PropertiesArc { GdkColor *color; gint size; /* We force circle by width = height */ gboolean filled; - RelPos position; + struct { + RelPosX x; + RelPosY y; + } position; }; struct _PropertiesBG { @@ -192,6 +218,8 @@ void draw_item( GdkDrawable *drawable, * process_states/ "name associated with LTTV_STATE_SYSCALL" */ + +#if 0 /* * The add_operation has to do a quick sort by priority to keep the operations * in the right order. @@ -233,42 +261,7 @@ void list_operations( LttvIAttribute *attributes, */ 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); - - - +#endif //0 /* * Here follow the prototypes of the hook functions used to draw the diff --git a/ltt/branches/poly/lttv/modules/gui/controlflow/eventhooks.c b/ltt/branches/poly/lttv/modules/gui/controlflow/eventhooks.c index ed2e3309..5b7d22b3 100644 --- a/ltt/branches/poly/lttv/modules/gui/controlflow/eventhooks.c +++ b/ltt/branches/poly/lttv/modules/gui/controlflow/eventhooks.c @@ -136,8 +136,7 @@ static void process_add(gpointer key, /* Action to do when background computation completed. * - * Eventually, will have to check that every requested traces are finished - * before doing the redraw. It will save unnecessary processor usage. + * Wait for all the awaited computations to be over. */ gint background_ready(void *hook_data, void *call_data) @@ -147,43 +146,28 @@ gint background_ready(void *hook_data, void *call_data) LttvTracesetContext *tsc = lttvwindow_get_traceset_context(control_flow_data->tab); - g_debug("control flow viewer : background computation data ready."); + control_flow_data->background_info_waiting--; + + if(control_flow_data->background_info_waiting == 0) { + g_debug("control flow viewer : background computation data ready."); - drawing_clear(control_flow_data->drawing); - processlist_clear(control_flow_data->process_list); -#if 0 - { - gint num_traces = lttv_traceset_number(tsc->ts); - gint i; - LttvTraceState *ts; - ProcessAddClosure closure; - closure.cfd = control_flow_data; - - for(i=0;itraces[i]; - - closure.trace_num = i; - - /* add all the processes to the list */ - lttv_state_for_each_process(ts, (GHFunc)process_add, &closure); - } + drawing_clear(control_flow_data->drawing); + processlist_clear(control_flow_data->process_list); + redraw_notify(control_flow_data, NULL); } -#endif //0 - redraw_notify(control_flow_data, NULL); return 0; } /* Request background computation. Verify if it is in progress or ready first. - * - * Right now, for all loaded traces. - * - * Later : must be only for each trace in the tab's traceset. + * Only for each trace in the tab's traceset. */ void request_background_data(ControlFlowData *control_flow_data) { - gint num_traces = lttvwindowtraces_get_number(); + LttvTracesetContext * tsc = + lttvwindow_get_traceset_context(control_flow_data->tab); + gint num_traces = lttv_traceset_number(tsc->ts); gint i; LttvTrace *trace; @@ -191,9 +175,10 @@ void request_background_data(ControlFlowData *control_flow_data) lttv_hooks_new(); lttv_hooks_add(background_ready_hook, background_ready, control_flow_data, LTTV_PRIO_DEFAULT); + control_flow_data->background_info_waiting = 0; for(i=0;its, i); if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace)==FALSE) { @@ -211,6 +196,7 @@ void request_background_data(ControlFlowData *control_flow_data) ltt_time_infinite, NULL, background_ready_hook); + control_flow_data->background_info_waiting++; } else { /* in progress */ lttvwindowtraces_background_notify_current(control_flow_data, @@ -218,7 +204,7 @@ void request_background_data(ControlFlowData *control_flow_data) ltt_time_infinite, NULL, background_ready_hook); - + control_flow_data->background_info_waiting++; } } } @@ -285,53 +271,31 @@ static __inline PropertiesLine prepare_line(LttvProcessState *process) PropertiesLine prop_line; prop_line.line_width = 2; prop_line.style = GDK_LINE_SOLID; - prop_line.position = MIDDLE; + prop_line.y = MIDDLE; + //GdkColormap *colormap = gdk_colormap_get_system(); g_debug("prepare_line for state : %s", g_quark_to_string(process->state->s)); /* color of line : status of the process */ if(process->state->s == LTTV_STATE_UNNAMED) - { - prop_line.color.red = 0xffff; - prop_line.color.green = 0xffff; - prop_line.color.blue = 0xffff; - } + prop_line.color = drawing_colors[COL_WHITE]; else if(process->state->s == LTTV_STATE_WAIT_FORK) - { - prop_line.color.red = 0x0fff; - prop_line.color.green = 0xffff; - prop_line.color.blue = 0xfff0; - } + prop_line.color = drawing_colors[COL_WAIT_FORK]; else if(process->state->s == LTTV_STATE_WAIT_CPU) - { - prop_line.color.red = 0xffff; - prop_line.color.green = 0xffff; - prop_line.color.blue = 0x0000; - } + prop_line.color = drawing_colors[COL_WAIT_CPU]; else if(process->state->s == LTTV_STATE_EXIT) - { - prop_line.color.red = 0xffff; - prop_line.color.green = 0x0000; - prop_line.color.blue = 0xffff; - } + prop_line.color = drawing_colors[COL_EXIT]; else if(process->state->s == LTTV_STATE_WAIT) - { - prop_line.color.red = 0xffff; - prop_line.color.green = 0x0000; - prop_line.color.blue = 0x0000; - } + prop_line.color = drawing_colors[COL_WAIT]; else if(process->state->s == LTTV_STATE_RUN) - { - prop_line.color.red = 0x0000; - prop_line.color.green = 0xffff; - prop_line.color.blue = 0x0000; - } + prop_line.color = drawing_colors[COL_RUN]; else - { - prop_line.color.red = 0xffff; - prop_line.color.green = 0xffff; - prop_line.color.blue = 0xffff; - } + prop_line.color = drawing_colors[COL_WHITE]; + + //gdk_colormap_alloc_color(colormap, + // prop_line.color, + // FALSE, + // TRUE); return prop_line; @@ -392,8 +356,8 @@ int draw_before_hook(void *hook_data, void *call_data) */ guint pid_out; + guint pid_in; { - guint pid_in; LttField *f = ltt_event_field(e); LttField *element; element = ltt_field_member(f,0); @@ -402,94 +366,204 @@ int draw_before_hook(void *hook_data, void *call_data) pid_in = ltt_event_get_long_unsigned(e,element); g_debug("out : %u in : %u", pid_out, pid_in); } - - /* First, check if the current process is in the state computation process - * list. If it is there, that means we must add it right now and draw items - * from the beginning of the read for it. If it is not present, it's a new - * process and it was not present : it will be added after the state update. - */ - LttvProcessState *process; - process = lttv_state_find_process(tfs, pid_out); - if(process != NULL) { - /* Well, the process_out existed : we must get it in the process hash - * or add it, and draw its items. - */ - /* Add process to process list (if not present) */ - guint y = 0, height = 0, pl_height = 0; - HashedProcessData *hashed_process_data = NULL; - ProcessList *process_list = - guicontrolflow_get_process_list(control_flow_data); - LttTime birth = process->creation_time; - const gchar *name = g_quark_to_string(process->name); + { + /* For the pid_out */ + /* First, check if the current process is in the state computation + * process list. If it is there, that means we must add it right now and + * draw items from the beginning of the read for it. If it is not + * present, it's a new process and it was not present : it will + * be added after the state update. */ + LttvProcessState *process; + process = lttv_state_find_process(tfs, pid_out); - if(processlist_get_process_pixels(process_list, + if(process != NULL) { + /* Well, the process_out existed : we must get it in the process hash + * or add it, and draw its items. + */ + /* Add process to process list (if not present) */ + guint y = 0, height = 0, pl_height = 0; + HashedProcessData *hashed_process_data = NULL; + ProcessList *process_list = + guicontrolflow_get_process_list(control_flow_data); + LttTime birth = process->creation_time; + const gchar *name = g_quark_to_string(process->name); + + if(processlist_get_process_pixels(process_list, + pid_out, + &birth, + tfc->t_context->index, + &y, + &height, + &hashed_process_data) == 1) + { + /* Process not present */ + processlist_add(process_list, pid_out, &birth, tfc->t_context->index, - &y, - &height, - &hashed_process_data) == 1) - { - /* Process not present */ - processlist_add(process_list, - pid_out, - &birth, - tfc->t_context->index, - name, - &pl_height, - &hashed_process_data); - processlist_get_process_pixels(process_list, - pid_out, + name, + &pl_height, + &hashed_process_data); + processlist_get_process_pixels(process_list, + pid_out, + &birth, + tfc->t_context->index, + &y, + &height, + &hashed_process_data); + drawing_insert_square( drawing, y, height); + } + + /* Now, the process is in the state hash and our own process hash. + * We definitely can draw the items related to the ending state. + */ + + /* Check if the x position is unset. In can have been left unset by + * a draw closure from a after chunk hook. This should never happen, + * because it must be set by before chunk hook to the damage_begin + * value. + */ + g_assert(hashed_process_data->x != -1); + { + guint x; + DrawContext draw_context; + + convert_time_to_pixels( + time_window.start_time, + end_time, + evtime, + width, + &x); + + /* Now create the drawing context that will be used to draw + * items related to the last state. */ + draw_context.drawable = drawing->pixmap; + draw_context.gc = drawing->gc; + draw_context.pango_layout = drawing->pango_layout; + draw_context.drawinfo.start.x = hashed_process_data->x; + draw_context.drawinfo.end.x = x; + + draw_context.drawinfo.y.over = y; + draw_context.drawinfo.y.middle = y+(height/4); + draw_context.drawinfo.y.under = y+(height/2)+2; + + draw_context.drawinfo.start.offset.over = 0; + draw_context.drawinfo.start.offset.middle = 0; + draw_context.drawinfo.start.offset.under = 0; + draw_context.drawinfo.end.offset.over = 0; + draw_context.drawinfo.end.offset.middle = 0; + draw_context.drawinfo.end.offset.under = 0; + + { + /* Draw the line */ + PropertiesLine prop_line = prepare_line(process); + draw_line((void*)&prop_line, (void*)&draw_context); + + } + /* become the last x position */ + hashed_process_data->x = x; + } + } + } + + { + /* For the pid_in */ + /* First, check if the current process is in the state computation + * process list. If it is there, that means we must add it right now and + * draw items from the beginning of the read for it. If it is not + * present, it's a new process and it was not present : it will + * be added after the state update. */ + LttvProcessState *process; + process = lttv_state_find_process(tfs, pid_in); + + if(process != NULL) { + /* Well, the process_out existed : we must get it in the process hash + * or add it, and draw its items. + */ + /* Add process to process list (if not present) */ + guint y = 0, height = 0, pl_height = 0; + HashedProcessData *hashed_process_data = NULL; + ProcessList *process_list = + guicontrolflow_get_process_list(control_flow_data); + LttTime birth = process->creation_time; + const gchar *name = g_quark_to_string(process->name); + + if(processlist_get_process_pixels(process_list, + pid_in, &birth, tfc->t_context->index, &y, &height, - &hashed_process_data); - drawing_insert_square( drawing, y, height); - } - - /* Now, the process is in the state hash and our own process hash. - * We definitely can draw the items related to the ending state. - */ + &hashed_process_data) == 1) + { + /* Process not present */ + processlist_add(process_list, + pid_in, + &birth, + tfc->t_context->index, + name, + &pl_height, + &hashed_process_data); + processlist_get_process_pixels(process_list, + pid_in, + &birth, + tfc->t_context->index, + &y, + &height, + &hashed_process_data); + drawing_insert_square( drawing, y, height); + } - /* Check if the x position is unset. In can have been left unset by - * a draw closure from a after chunk hook. This should never happen, - * because it must be set by before chunk hook to the damage_begin - * value. - */ - g_assert(hashed_process_data->x != -1); - { - guint x; - DrawContext draw_context; - - convert_time_to_pixels( - time_window.start_time, - end_time, - evtime, - width, - &x); - - /* Now create the drawing context that will be used to draw - * items related to the last state. */ - draw_context.drawable = drawing->pixmap; - draw_context.gc = drawing->gc; - draw_context.pango_layout = drawing->pango_layout; - draw_context.drawinfo.x_start = hashed_process_data->x; - draw_context.drawinfo.x_end = x; - - draw_context.drawinfo.y_over = y; - draw_context.drawinfo.y_middle = y+(height/4); - draw_context.drawinfo.y_under = y+(height/2)+2; - - draw_context.drawinfo.x_modify_over = hashed_process_data->x; - draw_context.drawinfo.x_modify_middle = hashed_process_data->x; - draw_context.drawinfo.x_modify_under = hashed_process_data->x; - + /* Now, the process is in the state hash and our own process hash. + * We definitely can draw the items related to the ending state. + */ + + /* Check if the x position is unset. In can have been left unset by + * a draw closure from a after chunk hook. This should never happen, + * because it must be set by before chunk hook to the damage_begin + * value. + */ + g_assert(hashed_process_data->x != -1); { - /* Draw the line */ - PropertiesLine prop_line = prepare_line(process); - draw_line((void*)&prop_line, (void*)&draw_context); + guint x; + DrawContext draw_context; + + convert_time_to_pixels( + time_window.start_time, + end_time, + evtime, + width, + &x); + + /* Now create the drawing context that will be used to draw + * items related to the last state. */ + draw_context.drawable = drawing->pixmap; + draw_context.gc = drawing->gc; + draw_context.pango_layout = drawing->pango_layout; + draw_context.drawinfo.start.x = hashed_process_data->x; + draw_context.drawinfo.end.x = x; + + draw_context.drawinfo.y.over = y; + draw_context.drawinfo.y.middle = y+(height/4); + draw_context.drawinfo.y.under = y+(height/2)+2; + + draw_context.drawinfo.start.offset.over = 0; + draw_context.drawinfo.start.offset.middle = 0; + draw_context.drawinfo.start.offset.under = 0; + draw_context.drawinfo.end.offset.over = 0; + draw_context.drawinfo.end.offset.middle = 0; + draw_context.drawinfo.end.offset.under = 0; + + { + /* Draw the line */ + PropertiesLine prop_line = prepare_line(process); + draw_line((void*)&prop_line, (void*)&draw_context); + } + + + /* become the last x position */ + hashed_process_data->x = x; } } } @@ -2038,7 +2112,7 @@ gint update_current_time_hook(void *hook_data, void *call_data) new_time_window.start_time = time_begin; new_time_window.time_width = width; - lttvwindow_report_time_window(control_flow_data->tab, &new_time_window); + lttvwindow_report_time_window(control_flow_data->tab, new_time_window); } else if(ltt_time_compare(current_time, time_end) == 1) { @@ -2052,7 +2126,7 @@ gint update_current_time_hook(void *hook_data, void *call_data) new_time_window.start_time = time_begin; new_time_window.time_width = width; - lttvwindow_report_time_window(control_flow_data->tab, &new_time_window); + lttvwindow_report_time_window(control_flow_data->tab, new_time_window); } //gtk_widget_queue_draw(control_flow_data->drawing->drawing_area); @@ -2071,229 +2145,164 @@ typedef struct _ClosureData { } ClosureData; -void draw_closure(gpointer key, gpointer value, gpointer user_data) +/* find_process + * Input : A trace and a PID. + * + * - For each CPU of the trace + * - Search in trace states by PID and CPU key + * - For each ProcessState found + * - If state is not LTTV_STATE_WAIT + * - Then this process state is the current one for this PID. + * - Stop search. + * - If no ProcessState found, return NULL. + * - If all ProcessState were in LTTV_STATE_WAIT state, return one of + * them arbitrarily. + * Than means state is LTTV_STATE_WAIT, CPU unknown. + */ +static LttvProcessState *find_process(LttvTraceState *tstate, guint pid) { - - return; + guint cpu_num = ltt_trace_per_cpu_tracefile_number(tstate->parent.t); + GQuark cpu_name; + guint i; + LttvProcessState *real_state = NULL; + + for(i=0;iparent.tracefiles[i])->cpu_name; + LttvProcessState *state = lttv_state_find_process_from_trace(tstate, + cpu_name, + pid); + + if(state != NULL) { + real_state = state; + if(state->state->s != LTTV_STATE_WAIT) + break; + } + } + return real_state; +} -#if 0 + +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->events_request->viewer_data; - - GtkWidget *widget = control_flow_data->drawing->drawing_area; + EventsRequest *events_request = closure_data->events_request; + ControlFlowData *control_flow_data = events_request->viewer_data; + Drawing_t *drawing = control_flow_data->drawing; - /* 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 = - ((LttvTracesetContext*)closure_data->tss)->traces[process_info->trace_num]; - LttvTracesetContext *tsc = (LttvTracesetContext *)closure_data->tss; - - LttvTraceState *ts = (LttvTraceState*)tc; - LttvProcessState *process; - - /* We do not provide a cpu_name argument assuming that this is not the - idle job (pid 0) and thus its pid is unique across all cpus */ - process = lttv_state_find_process_from_trace(ts, 0, 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->over->x = - control_flow_data->drawing->damage_begin; - draw_context->previous->middle->x = - control_flow_data->drawing->damage_begin; - draw_context->previous->under->x = - control_flow_data->drawing->damage_begin; - - g_debug("out middle x_beg : %u",control_flow_data->drawing->damage_begin); - } + LttvTracesetState *tss = closure_data->tss; + LttvTracesetContext *tsc = (LttvTracesetContext*)closure_data->tss; - /* Find pixels corresponding to current time . 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->width; + LttTime evtime = closure_data->end_time; + TimeWindow time_window = + lttvwindow_get_time_window(control_flow_data->tab); - TimeWindow time_window = - lttvwindow_get_time_window(control_flow_data->tab); + LttTime end_time = ltt_time_add(time_window.start_time, + time_window.time_width); - LttTime time = lttv_traceset_context_get_current_tfc(tsc)->timestamp; + if(ltt_time_compare(evtime, time_window.start_time) == -1 + || ltt_time_compare(evtime, end_time) == 1) + return; - LttTime window_end = ltt_time_add(time_window.time_width, - time_window.start_time); - - convert_time_to_pixels( - time_window.start_time, - window_end, - time, - width, - &x); - - draw_context->current->middle->x = x; - draw_context->current->over->x = x; - draw_context->current->under->x = x; - draw_context->current->middle->y = y + height/2; - draw_context->current->over->y = y ; - draw_context->current->under->y = y + height; - draw_context->previous->middle->y = y + height/2; - draw_context->previous->over->y = y ; - draw_context->previous->under->y = y + height; - 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); - draw_context->gc = control_flow_data->drawing->gc; - - if(process != NULL && process->state->s == LTTV_STATE_RUN) - { - PropertiesBG prop_bg; - prop_bg.color = g_new(GdkColor,1); - - /*switch(tfc->index) { - case 0: - prop_bg.color->red = 0x1515; - prop_bg.color->green = 0x1515; - prop_bg.color->blue = 0x8c8c; - break; - case 1: - prop_bg.color->red = 0x4e4e; - prop_bg.color->green = 0xa9a9; - prop_bg.color->blue = 0xa4a4; - break; - case 2: - prop_bg.color->red = 0x7a7a; - prop_bg.color->green = 0x4a4a; - prop_bg.color->blue = 0x8b8b; - break; - case 3: - prop_bg.color->red = 0x8080; - prop_bg.color->green = 0x7777; - prop_bg.color->blue = 0x4747; - break; - default: - prop_bg.color->red = 0xe7e7; - prop_bg.color->green = 0xe7e7; - prop_bg.color->blue = 0xe7e7; - } - */ + guint width = drawing->width; - g_debug("calling from closure"); - //FIXME : I need the cpu number in process's state to draw this. - //draw_bg((void*)&prop_bg, (void*)draw_context); - g_free(prop_bg.color); - } + { + /* For the process */ + /* First, check if the current process is in the state computation + * process list. If it is there, that means we must add it right now and + * draw items from the beginning of the read for it. If it is not + * present, it's a new process and it was not present : it will + * be added after the state update. */ + g_assert(lttv_traceset_number(tsc->ts) > 0); + LttvTraceState *trace_state = + (LttvTraceState*)tsc->traces[process_info->trace_num]; - PropertiesLine prop_line; - prop_line.color = g_new(GdkColor,1); - prop_line.line_width = 2; - prop_line.style = GDK_LINE_SOLID; - prop_line.position = MIDDLE; + LttvProcessState *process; + process = find_process(trace_state, process_info->pid); - /* color of line : status of the process */ - if(process != NULL) - { - if(process->state->s == LTTV_STATE_UNNAMED) - { - prop_line.color->red = 0xffff; - prop_line.color->green = 0xffff; - prop_line.color->blue = 0xffff; - } - else if(process->state->s == LTTV_STATE_WAIT_FORK) - { - prop_line.color->red = 0x0fff; - prop_line.color->green = 0xffff; - prop_line.color->blue = 0xfff0; - } - else if(process->state->s == LTTV_STATE_WAIT_CPU) - { - prop_line.color->red = 0xffff; - prop_line.color->green = 0xffff; - 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 = 0xffff; - prop_line.color->green = 0xffff; - prop_line.color->blue = 0xffff; - } + if(process != NULL) { + + /* Only draw for processes that are currently in the trace states */ - } - else - { - prop_line.color->red = 0xffff; - prop_line.color->green = 0xffff; - prop_line.color->blue = 0xffff; - } + guint y = 0, height = 0, pl_height = 0; + ProcessList *process_list = + guicontrolflow_get_process_list(control_flow_data); + LttTime birth = process_info->birth; + + /* Should be alike when background info is ready */ + if(control_flow_data->background_info_waiting==0) + g_assert(ltt_time_compare(process->creation_time, + process_info->birth) == 0); + const gchar *name = g_quark_to_string(process->name); + + /* process HAS to be present */ + g_assert(processlist_get_process_pixels(process_list, + process_info->pid, + &birth, + process_info->trace_num, + &y, + &height, + &hashed_process_data) != 1); + + /* Now, the process is in the state hash and our own process hash. + * We definitely can draw the items related to the ending state. + */ + + /* Check if the x position is unset. In can have been left unset by + * a draw closure from a after chunk hook. This should never happen, + * because it must be set by before chunk hook to the damage_begin + * value. + */ + g_assert(hashed_process_data->x != -1); + { + guint x; + DrawContext draw_context; - 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; + convert_time_to_pixels( + time_window.start_time, + end_time, + evtime, + width, + &x); -#endif //0 + /* Now create the drawing context that will be used to draw + * items related to the last state. */ + draw_context.drawable = drawing->pixmap; + draw_context.gc = drawing->gc; + draw_context.pango_layout = drawing->pango_layout; + draw_context.drawinfo.start.x = hashed_process_data->x; + draw_context.drawinfo.end.x = x; + + draw_context.drawinfo.y.over = y; + draw_context.drawinfo.y.middle = y+(height/4); + draw_context.drawinfo.y.under = y+(height/2)+2; + + draw_context.drawinfo.start.offset.over = 0; + draw_context.drawinfo.start.offset.middle = 0; + draw_context.drawinfo.start.offset.under = 0; + draw_context.drawinfo.end.offset.over = 0; + draw_context.drawinfo.end.offset.middle = 0; + draw_context.drawinfo.end.offset.under = 0; + + { + /* Draw the line */ + PropertiesLine prop_line = prepare_line(process); + draw_line((void*)&prop_line, (void*)&draw_context); + + } + + /* special case LTTV_STATE_WAIT : CPU is unknown. */ + + /* become the last x position */ + hashed_process_data->x = x; + } + } + } + return; } int before_chunk(void *hook_data, void *call_data) @@ -2354,7 +2363,7 @@ int after_request(void *hook_data, void *call_data) /* * for each process * draw closing line - * expose + * expose */ int after_chunk(void *hook_data, void *call_data) { @@ -2368,9 +2377,8 @@ int after_chunk(void *hook_data, void *call_data) ProcessList *process_list = guicontrolflow_get_process_list(control_flow_data); - if(tfc != NULL - && ltt_time_compare(tfc->timestamp, events_request->end_time) <= 0) - end_time = tfc->timestamp; + if(tfc != NULL) + end_time = LTT_TIME_MIN(tfc->timestamp, events_request->end_time); else /* end of traceset, or position now out of request : end */ end_time = events_request->end_time; diff --git a/ltt/branches/poly/lttv/modules/gui/controlflow/processlist.c b/ltt/branches/poly/lttv/modules/gui/controlflow/processlist.c index bc12c7d2..55715cd8 100644 --- a/ltt/branches/poly/lttv/modules/gui/controlflow/processlist.c +++ b/ltt/branches/poly/lttv/modules/gui/controlflow/processlist.c @@ -352,26 +352,6 @@ static gboolean remove_hash_item(ProcessInfo *process_info, gtk_list_store_remove (process_list->list_store, &iter); -#if 0 - 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); -#endif //0 - - return TRUE; /* remove the element from the hash table */ } @@ -557,24 +537,7 @@ int processlist_remove( ProcessList *process_list, gtk_tree_path_free(tree_path); gtk_list_store_remove (process_list->list_store, &iter); -#if 0 - 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); -#endif //0 + g_hash_table_remove(process_list->process_hash, &Process_Info); diff --git a/ltt/branches/poly/lttv/modules/gui/detailedevents/events.c b/ltt/branches/poly/lttv/modules/gui/detailedevents/events.c index 3a367b26..c714031b 100644 --- a/ltt/branches/poly/lttv/modules/gui/detailedevents/events.c +++ b/ltt/branches/poly/lttv/modules/gui/detailedevents/events.c @@ -678,7 +678,7 @@ void tree_v_cursor_changed_cb (GtkWidget *widget, gpointer data) if(ltt_time.tv_sec != current_time.tv_sec || ltt_time.tv_nsec != current_time.tv_nsec){ event_viewer_data->current_time_updated = TRUE; - lttvwindow_report_current_time(tab,<t_time); + lttvwindow_report_current_time(tab,ltt_time); } }else{ g_warning("Can not get iter\n"); diff --git a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c index 4ec7864f..d7da3f4c 100644 --- a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c +++ b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c @@ -241,6 +241,8 @@ int SetTraceset(Tab * tab, LttvTraceset *traceset) LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context); TimeInterval time_span = tsc->time_span; + TimeWindow new_time_window; + LttTime new_current_time; /* Set the tab's time window and current time if * out of bounds */ @@ -248,8 +250,9 @@ int SetTraceset(Tab * tab, LttvTraceset *traceset) || ltt_time_compare( ltt_time_add(tab->time_window.start_time, tab->time_window.time_width), time_span.end_time) > 0) { - tab->time_window.start_time = time_span.start_time; - tab->current_time = time_span.start_time; + new_time_window.start_time = time_span.start_time; + + new_current_time = time_span.start_time; LttTime tmp_time; @@ -258,9 +261,12 @@ int SetTraceset(Tab * tab, LttvTraceset *traceset) else tmp_time.tv_sec = time_span.end_time.tv_sec; tmp_time.tv_nsec = 0; - tab->time_window.time_width = tmp_time ; + new_time_window.time_width = tmp_time ; } - + time_change_manager(tab, new_time_window); + current_time_change_manager(tab, new_current_time); + +#if 0 /* Set scrollbar */ GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(tab->scrollbar)); LttTime upper = ltt_time_sub(time_span.end_time, time_span.start_time); @@ -292,6 +298,23 @@ int SetTraceset(Tab * tab, LttvTraceset *traceset) NULL); gtk_adjustment_value_changed(adjustment); + /* set the time bar. The value callbacks will change their nsec themself */ + /* start seconds */ + gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry1), + (double)time_span.start_time.tv_sec, + (double)time_span.end_time.tv_sec); + + /* end seconds */ + gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry3), + (double)time_span.start_time.tv_sec, + (double)time_span.end_time.tv_sec); + + /* current seconds */ + gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry5), + (double)time_span.start_time.tv_sec, + (double)time_span.end_time.tv_sec); +#endif //0 + /* Finally, call the update hooks of the viewers */ LttvHooks * tmp; LttvAttributeValue value; @@ -2008,6 +2031,8 @@ void zoom(GtkWidget * widget, double size) == 0 ) { g_warning("Can not zoom that far due to time nanosecond precision"); } else { + time_change_manager(tab, new_time_window); +#if 0 /* Set scrollbar */ GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(tab->scrollbar)); @@ -2054,6 +2079,7 @@ void zoom(GtkWidget * widget, double size) //gtk_adjustment_set_value(adjustment, // ltt_time_to_double(new_time_window.start_time) // * NANOSECONDS_PER_SECOND); +#endif //0 } } @@ -2074,7 +2100,7 @@ void zoom_extended(GtkWidget * widget, gpointer user_data) void go_to_time(GtkWidget * widget, gpointer user_data) { - g_printf("Go to time\n"); + g_printf("Go to time\n"); } void show_time_frame(GtkWidget * widget, gpointer user_data) @@ -3157,19 +3183,396 @@ on_MNotebook_switch_page (GtkNotebook *notebook, } +void time_change_manager (Tab *tab, + TimeWindow new_time_window) +{ + /* Only one source of time change */ + if(tab->time_manager_lock == TRUE) return; + + tab->time_manager_lock = TRUE; + + LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context); + TimeInterval time_span = tsc->time_span; + LttTime start_time = new_time_window.start_time; + LttTime end_time = ltt_time_add(new_time_window.start_time, + new_time_window.time_width); + + /* Set scrollbar */ + GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(tab->scrollbar)); + LttTime upper = ltt_time_sub(time_span.end_time, time_span.start_time); +#if 0 + gtk_range_set_increments(GTK_RANGE(tab->scrollbar), + ltt_time_to_double(new_time_window.time_width) + / SCROLL_STEP_PER_PAGE + * NANOSECONDS_PER_SECOND, /* step increment */ + ltt_time_to_double(new_time_window.time_width) + * NANOSECONDS_PER_SECOND); /* page increment */ + gtk_range_set_range(GTK_RANGE(tab->scrollbar), + 0.0, /* lower */ + ltt_time_to_double(upper) + * NANOSECONDS_PER_SECOND); /* upper */ +#endif //0 + g_object_set(G_OBJECT(adjustment), + "lower", + 0.0, /* lower */ + "upper", + ltt_time_to_double(upper) + * NANOSECONDS_PER_SECOND, /* upper */ + "step_increment", + ltt_time_to_double(new_time_window.time_width) + / SCROLL_STEP_PER_PAGE + * NANOSECONDS_PER_SECOND, /* step increment */ + "page_increment", + ltt_time_to_double(new_time_window.time_width) + * NANOSECONDS_PER_SECOND, /* page increment */ + "page_size", + ltt_time_to_double(new_time_window.time_width) + * NANOSECONDS_PER_SECOND, /* page size */ + NULL); + gtk_adjustment_changed(adjustment); + + // g_object_set(G_OBJECT(adjustment), + // "value", + // ltt_time_to_double( + // ltt_time_sub(start_time, time_span.start_time)) + // * NANOSECONDS_PER_SECOND, /* value */ + // NULL); + //gtk_adjustment_value_changed(adjustment); + gtk_range_set_value(GTK_RANGE(tab->scrollbar), + ltt_time_to_double( + ltt_time_sub(start_time, time_span.start_time)) + * NANOSECONDS_PER_SECOND /* value */); + + /* set the time bar. */ + /* start seconds */ + gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry1), + (double)time_span.start_time.tv_sec, + (double)time_span.end_time.tv_sec); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry1), + (double)start_time.tv_sec); + + /* start nanoseconds */ + if(start_time.tv_sec == time_span.start_time.tv_sec) { + gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2), + (double)time_span.start_time.tv_nsec, + (double)NANOSECONDS_PER_SECOND-1); + } + else if(start_time.tv_sec == time_span.end_time.tv_sec) { + /* If we are at the end, max nsec to end.. -1 (not zero length) */ + gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2), + 0.0, + (double)time_span.end_time.tv_nsec-1); + } + else /* anywhere else */ + gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2), + 0.0, + (double)NANOSECONDS_PER_SECOND-1); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry2), + (double)start_time.tv_nsec); + + /* end seconds */ + gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry3), + (double)time_span.start_time.tv_sec, + (double)time_span.end_time.tv_sec); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry3), + (double)end_time.tv_sec); + + /* end nanoseconds */ + if(end_time.tv_sec == time_span.start_time.tv_sec) { + gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4), + (double)time_span.start_time.tv_nsec+1, + (double)NANOSECONDS_PER_SECOND-1); + } + else if(end_time.tv_sec == time_span.end_time.tv_sec) { + /* If we are at the end, max nsec to end.. */ + gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4), + 0.0, + (double)time_span.end_time.tv_nsec); + } + else /* anywhere else */ + gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4), + 0.0, + (double)NANOSECONDS_PER_SECOND-1); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry4), + (double)end_time.tv_nsec); + + /* call viewer hooks for new time window */ + set_time_window(tab, &new_time_window); + + tab->time_manager_lock = FALSE; +} + + +/* value changed for frame start s + * + * Check time span : if ns is out of range, clip it the nearest good value. + */ +void +on_MEntry1_value_changed (GtkSpinButton *spinbutton, + gpointer user_data) +{ + Tab *tab =(Tab *)user_data; + LttvTracesetContext * tsc = + LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context); + TimeInterval time_span = tsc->time_span; + gint value = gtk_spin_button_get_value_as_int(spinbutton); + + TimeWindow new_time_window = tab->time_window; + + LttTime end_time = ltt_time_add(new_time_window.start_time, + new_time_window.time_width); + + new_time_window.start_time.tv_sec = value; + + /* start nanoseconds */ + if(new_time_window.start_time.tv_sec == time_span.start_time.tv_sec) { + if(new_time_window.start_time.tv_nsec < time_span.start_time.tv_nsec) + new_time_window.start_time.tv_nsec = time_span.start_time.tv_nsec; + } + else if(new_time_window.start_time.tv_sec == time_span.end_time.tv_sec) { + if(new_time_window.start_time.tv_nsec > time_span.end_time.tv_nsec) + new_time_window.start_time.tv_nsec = time_span.end_time.tv_nsec-1; + } + + /* check if end time selected is below or equal */ + if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) { + /* Then, we must push back end time : keep the same time width + * if possible, else end traceset time */ + end_time = LTT_TIME_MIN(time_span.end_time, + ltt_time_add(new_time_window.start_time, + new_time_window.time_width) + ); + } + + /* Fix the time width to fit start time and end time */ + new_time_window.time_width = ltt_time_sub(end_time, + new_time_window.start_time); + + time_change_manager(tab, new_time_window); + +} + +void +on_MEntry2_value_changed (GtkSpinButton *spinbutton, + gpointer user_data) +{ + Tab *tab =(Tab *)user_data; + LttvTracesetContext * tsc = + LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context); + TimeInterval time_span = tsc->time_span; + gint value = gtk_spin_button_get_value_as_int(spinbutton); + + TimeWindow new_time_window = tab->time_window; + + LttTime end_time = ltt_time_add(new_time_window.start_time, + new_time_window.time_width); + + new_time_window.start_time.tv_nsec = value; + + /* check if end time selected is below or equal */ + if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) { + /* Then, we must push back end time : keep the same time width + * if possible, else end traceset time */ + end_time = LTT_TIME_MIN(time_span.end_time, + ltt_time_add(new_time_window.start_time, + new_time_window.time_width) + ); + } + + /* Fix the time width to fit start time and end time */ + new_time_window.time_width = ltt_time_sub(end_time, + new_time_window.start_time); + + time_change_manager(tab, new_time_window); + +} + +void +on_MEntry3_value_changed (GtkSpinButton *spinbutton, + gpointer user_data) +{ + Tab *tab =(Tab *)user_data; + LttvTracesetContext * tsc = + LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context); + TimeInterval time_span = tsc->time_span; + gint value = gtk_spin_button_get_value_as_int(spinbutton); + + TimeWindow new_time_window = tab->time_window; + + LttTime end_time = ltt_time_add(new_time_window.start_time, + new_time_window.time_width); + end_time.tv_sec = value; + + /* end nanoseconds */ + if(end_time.tv_sec == time_span.start_time.tv_sec) { + if(end_time.tv_nsec < time_span.start_time.tv_nsec) + end_time.tv_nsec = time_span.start_time.tv_nsec+1; + } + else if(end_time.tv_sec == time_span.end_time.tv_sec) { + if(end_time.tv_nsec > time_span.end_time.tv_nsec) + end_time.tv_nsec = time_span.end_time.tv_nsec; + } + + /* check if end time selected is below or equal */ + if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) { + /* Then, we must push front start time : keep the same time width + * if possible, else end traceset time */ + new_time_window.start_time = LTT_TIME_MAX(time_span.start_time, + ltt_time_sub(end_time, + new_time_window.time_width) + ); + } + + /* Fix the time width to fit start time and end time */ + new_time_window.time_width = ltt_time_sub(end_time, + new_time_window.start_time); + + time_change_manager(tab, new_time_window); + +} + +void +on_MEntry4_value_changed (GtkSpinButton *spinbutton, + gpointer user_data) +{ + Tab *tab =(Tab *)user_data; + LttvTracesetContext * tsc = + LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context); + TimeInterval time_span = tsc->time_span; + gint value = gtk_spin_button_get_value_as_int(spinbutton); + + TimeWindow new_time_window = tab->time_window; + + LttTime end_time = ltt_time_add(new_time_window.start_time, + new_time_window.time_width); + end_time.tv_nsec = value; + + /* check if end time selected is below or equal */ + if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) { + /* Then, we must push front start time : keep the same time width + * if possible, else end traceset time */ + new_time_window.start_time = LTT_TIME_MAX(time_span.start_time, + ltt_time_sub(end_time, + new_time_window.time_width) + ); + } + + /* Fix the time width to fit start time and end time */ + new_time_window.time_width = ltt_time_sub(end_time, + new_time_window.start_time); + + time_change_manager(tab, new_time_window); + +} + + +void current_time_change_manager (Tab *tab, + LttTime new_current_time) +{ + /* Only one source of time change */ + if(tab->current_time_manager_lock == TRUE) return; + + tab->current_time_manager_lock = TRUE; + + LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context); + TimeInterval time_span = tsc->time_span; + + tab->current_time = new_current_time; + + /* current seconds */ + gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry5), + (double)time_span.start_time.tv_sec, + (double)time_span.end_time.tv_sec); + + /* start nanoseconds */ + if(new_current_time.tv_sec == time_span.start_time.tv_sec) { + gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6), + (double)time_span.start_time.tv_nsec, + (double)NANOSECONDS_PER_SECOND-1); + } + else if(new_current_time.tv_sec == time_span.end_time.tv_sec) { + /* If we are at the end, max nsec to end.. */ + gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6), + 0.0, + (double)time_span.end_time.tv_nsec); + } + else /* anywhere else */ + gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6), + 0.0, + (double)NANOSECONDS_PER_SECOND-1); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry6), + (double)new_current_time.tv_nsec); + + lttvwindow_report_current_time(tab, tab->current_time); + + tab->current_time_manager_lock = FALSE; +} + +void +on_MEntry5_value_changed (GtkSpinButton *spinbutton, + gpointer user_data) +{ + Tab *tab = (Tab*)user_data; + LttvTracesetContext * tsc = + LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context); + TimeInterval time_span = tsc->time_span; + gint value = gtk_spin_button_get_value_as_int(spinbutton); + LttTime new_current_time = tab->current_time; + new_current_time.tv_sec = value; + + /* current nanoseconds */ + if(new_current_time.tv_sec == time_span.start_time.tv_sec) { + if(new_current_time.tv_nsec < time_span.start_time.tv_nsec) + new_current_time.tv_nsec = time_span.start_time.tv_nsec; + } + else if(new_current_time.tv_sec == time_span.end_time.tv_sec) { + if(new_current_time.tv_nsec > time_span.end_time.tv_nsec) + new_current_time.tv_nsec = time_span.end_time.tv_nsec; + } + + current_time_change_manager(tab, new_current_time); +} + +void +on_MEntry6_value_changed (GtkSpinButton *spinbutton, + gpointer user_data) +{ + Tab *tab = (Tab*)user_data; + gint value = gtk_spin_button_get_value_as_int(spinbutton); + LttTime new_current_time = tab->current_time; + new_current_time.tv_nsec = value; + + current_time_change_manager(tab, new_current_time); +} + + void scroll_value_changed_cb(GtkWidget *scrollbar, gpointer user_data) { Tab *tab = (Tab *)user_data; - TimeWindow time_window; + TimeWindow new_time_window; LttTime time; GtkAdjustment *adjust = gtk_range_get_adjustment(GTK_RANGE(scrollbar)); gdouble value = gtk_adjustment_get_value(adjust); - gdouble upper, lower, ratio, page_size; + // gdouble upper, lower, ratio, page_size; + gdouble page_size; LttvTracesetContext * tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context); TimeInterval time_span = tsc->time_span; + time = ltt_time_add(ltt_time_from_double(value/NANOSECONDS_PER_SECOND), + time_span.start_time); + + new_time_window.start_time = time; + + page_size = adjust->page_size; + + new_time_window.time_width = + ltt_time_from_double(page_size/NANOSECONDS_PER_SECOND); + + + time_change_manager(tab, new_time_window); +#if 0 //time_window = tab->time_window; lower = adjust->lower; @@ -3196,7 +3599,7 @@ void scroll_value_changed_cb(GtkWidget *scrollbar, /* call viewer hooks for new time window */ set_time_window(tab, &time_window); - +#endif //0 } @@ -3662,7 +4065,6 @@ void construct_main_window(MainWindow * parent) // Add the object's information to the module's array g_main_window_list = g_slist_append(g_main_window_list, new_m_window); - new_window = create_MWindow(); gtk_widget_show (new_window); @@ -3689,7 +4091,7 @@ void construct_main_window(MainWindow * parent) g_printf("Notebook does not exist\n"); return; } - gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook)); + //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook)); //for now there is no name field in LttvTraceset structure //Use "Traceset" as the label for the default tab if(parent) { @@ -3711,9 +4113,9 @@ void construct_main_window(MainWindow * parent) lttvwindow_add_trace(new_tab, g_init_trace); - LttvTraceset *traceset = new_tab->traceset_info->traceset; - SetTraceset(new_tab, traceset); } + LttvTraceset *traceset = new_tab->traceset_info->traceset; + SetTraceset(new_tab, traceset); } g_printf("There are now : %d windows\n",g_slist_length(g_main_window_list)); @@ -3796,6 +4198,8 @@ Tab* create_tab(MainWindow * mw, Tab *copy_tab, fflush(stdout); #endif //DEBUG + tab->time_manager_lock = FALSE; + tab->current_time_manager_lock = FALSE; //FIXME copy not implemented in lower level tab->traceset_info->traceset_context = @@ -3809,6 +4213,7 @@ Tab* create_tab(MainWindow * mw, Tab *copy_tab, (LttvTracesetState*)tab->traceset_info->traceset_context); //determine the current_time and time_window of the tab +#if 0 if(copy_tab != NULL){ tab->time_window = copy_tab->time_window; tab->current_time = copy_tab->current_time; @@ -3833,6 +4238,7 @@ Tab* create_tab(MainWindow * mw, Tab *copy_tab, LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)-> time_span.start_time.tv_nsec; } +#endif //0 tab->attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL)); tab->interrupted_state = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); @@ -3846,13 +4252,94 @@ Tab* create_tab(MainWindow * mw, Tab *copy_tab, TRUE, /* expand */ TRUE, /* Give the extra space to the child */ 0); /* No padding */ - + + /* Create the timebar */ + { + tab->MTimebar = gtk_hbox_new(FALSE, 2); + gtk_widget_show(tab->MTimebar); + + tab->MText1 = gtk_label_new("Time Frame start: "); + gtk_widget_show(tab->MText1); + tab->MText2 = gtk_label_new("s"); + gtk_widget_show(tab->MText2); + tab->MText3a = gtk_label_new("ns"); + gtk_widget_show(tab->MText3a); + tab->MText3b = gtk_label_new("end:"); + gtk_widget_show(tab->MText3b); + tab->MText4 = gtk_label_new("s"); + gtk_widget_show(tab->MText4); + tab->MText5a = gtk_label_new("ns"); + gtk_widget_show(tab->MText5a); + tab->MText5b = gtk_label_new("Current Time:"); + gtk_widget_show(tab->MText5b); + tab->MText6 = gtk_label_new("s"); + gtk_widget_show(tab->MText6); + tab->MText7 = gtk_label_new("ns"); + gtk_widget_show(tab->MText7); + + tab->MEntry1 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0); + gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry1),0); + gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry1),TRUE); + gtk_widget_show(tab->MEntry1); + tab->MEntry2 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0); + gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry2),0); + gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry2),TRUE); + gtk_widget_show(tab->MEntry2); + tab->MEntry3 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0); + gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry3),0); + gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry3),TRUE); + gtk_widget_show(tab->MEntry3); + tab->MEntry4 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0); + gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry4),0); + gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry4),TRUE); + gtk_widget_show(tab->MEntry4); + tab->MEntry5 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0); + gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry5),0); + gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry5),TRUE); + gtk_widget_show(tab->MEntry5); + tab->MEntry6 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0); + gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry6),0); + gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry6),TRUE); + gtk_widget_show(tab->MEntry6); + + + GtkWidget *temp_widget; + + gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText1, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry1, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText2, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry2, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText3a, FALSE, FALSE, 0); + temp_widget = gtk_vseparator_new(); + gtk_widget_show(temp_widget); + gtk_box_pack_start (GTK_BOX (tab->MTimebar), temp_widget, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText3b, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry3, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText4, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry4, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText5a, FALSE, FALSE, 0); + temp_widget = gtk_vseparator_new(); + gtk_widget_show(temp_widget); + gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MText7, FALSE, FALSE, 0); + gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MEntry6, FALSE, FALSE, 0); + gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MText6, FALSE, FALSE, 0); + gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MEntry5, FALSE, FALSE, 0); + gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MText5b, FALSE, FALSE, 0); + gtk_box_pack_end (GTK_BOX (tab->MTimebar), temp_widget, FALSE, FALSE, 0); + } + gtk_box_pack_end(GTK_BOX(tab->vbox), tab->scrollbar, FALSE, /* Do not expand */ FALSE, /* Fill has no effect here (expand false) */ 0); /* No padding */ - + + gtk_box_pack_end(GTK_BOX(tab->vbox), + tab->MTimebar, + FALSE, /* Do not expand */ + FALSE, /* Fill has no effect here (expand false) */ + 0); /* No padding */ + g_object_set_data(G_OBJECT(tab->viewer_container), "focused_viewer", NULL); @@ -3909,6 +4396,26 @@ Tab* create_tab(MainWindow * mw, Tab *copy_tab, g_signal_connect(G_OBJECT(tab->scrollbar), "value-changed", G_CALLBACK(scroll_value_changed_cb), tab); + + g_signal_connect ((gpointer) tab->MEntry1, "value-changed", + G_CALLBACK (on_MEntry1_value_changed), + tab); + g_signal_connect ((gpointer) tab->MEntry2, "value-changed", + G_CALLBACK (on_MEntry2_value_changed), + tab); + g_signal_connect ((gpointer) tab->MEntry3, "value-changed", + G_CALLBACK (on_MEntry3_value_changed), + tab); + g_signal_connect ((gpointer) tab->MEntry4, "value-changed", + G_CALLBACK (on_MEntry4_value_changed), + tab); + g_signal_connect ((gpointer) tab->MEntry5, "value-changed", + G_CALLBACK (on_MEntry5_value_changed), + tab); + g_signal_connect ((gpointer) tab->MEntry6, "value-changed", + G_CALLBACK (on_MEntry6_value_changed), + tab); + //g_signal_connect(G_OBJECT(tab->scrollbar), "changed", // G_CALLBACK(scroll_value_changed_cb), tab); diff --git a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.h b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.h index 27ef9c28..348e47ea 100644 --- a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.h +++ b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.h @@ -283,4 +283,31 @@ on_MNotebook_switch_page (GtkNotebook *notebook, guint page_num, gpointer user_data); + +void +on_MEntry1_value_changed (GtkSpinButton *spinbutton, + gpointer user_data); +void +on_MEntry2_value_changed (GtkSpinButton *spinbutton, + gpointer user_data); +void +on_MEntry3_value_changed (GtkSpinButton *spinbutton, + gpointer user_data); +void +on_MEntry4_value_changed (GtkSpinButton *spinbutton, + gpointer user_data); +void +on_MEntry5_value_changed (GtkSpinButton *spinbutton, + gpointer user_data); +void +on_MEntry6_value_changed (GtkSpinButton *spinbutton, + gpointer user_data); + + +void time_change_manager (Tab *tab, + TimeWindow new_time_window); + +void current_time_change_manager (Tab *tab, + LttTime new_current_time); + gboolean execute_time_requests(MainWindow * mw); diff --git a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/interface.c b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/interface.c index 2c528f10..86f0ba76 100644 --- a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/interface.c +++ b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/interface.c @@ -128,8 +128,8 @@ create_MWindow (void) GtkWidget *tlbZoomIn; GtkWidget *tlbZoomOut; GtkWidget *tlbZoomExtended; - // GtkWidget *tlbGoToTime; - // GtkWidget *tlbShowTimeFrame; + //GtkWidget *tlbGoToTime; + //GtkWidget *tlbShowTimeFrame; GtkWidget *tlbMoveViewerUp; GtkWidget *tlbMoveViewerDown; GtkWidget *tlbRemoveViewer; @@ -565,7 +565,8 @@ create_MWindow (void) gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (MToolbar1)->children)->data))->label), TRUE); gtk_widget_show (tlbZoomExtended); gtk_container_set_border_width (GTK_CONTAINER (tlbZoomExtended), 1); -/* + + /* tmp_toolbar_icon = create_pixmap (MWindow, "gtk-jump-to.png"); tlbGoToTime = gtk_toolbar_append_element (GTK_TOOLBAR (MToolbar1), GTK_TOOLBAR_CHILD_BUTTON, @@ -587,7 +588,7 @@ create_MWindow (void) gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (MToolbar1)->children)->data))->label), TRUE); gtk_widget_show (tlbShowTimeFrame); gtk_container_set_border_width (GTK_CONTAINER (tlbShowTimeFrame), 1); -*/ + */ gtk_toolbar_append_space (GTK_TOOLBAR (MToolbar1)); tmp_toolbar_icon = create_pixmap (MWindow, "1uparrow.png"); @@ -634,6 +635,7 @@ create_MWindow (void) gtk_widget_show (MNotebook); gtk_notebook_set_show_tabs((GtkNotebook*)MNotebook, FALSE); gtk_box_pack_start (GTK_BOX (MVbox), MNotebook, TRUE, TRUE, 0); + /* empty_notebook_page = gtk_vbox_new (FALSE, 0); gtk_widget_show (empty_notebook_page); @@ -819,14 +821,14 @@ create_MWindow (void) g_signal_connect ((gpointer) tlbZoomExtended, "clicked", G_CALLBACK (on_button_zoom_extended_clicked), NULL); -/* + /* g_signal_connect ((gpointer) tlbGoToTime, "clicked", G_CALLBACK (on_button_go_to_time_clicked), NULL); g_signal_connect ((gpointer) tlbShowTimeFrame, "clicked", G_CALLBACK (on_button_show_time_frame_clicked), NULL); -*/ + */ g_signal_connect ((gpointer) tlbMoveViewerUp, "clicked", G_CALLBACK (on_button_move_up_clicked), NULL); diff --git a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.c b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.c index 076045bf..a37077e3 100644 --- a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.c +++ b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.c @@ -678,17 +678,20 @@ void lttvwindow_unregister_dividor(Tab *tab, */ void lttvwindow_report_time_window(Tab *tab, - const TimeWindow *time_window) + TimeWindow time_window) { //set_time_window(tab, time_window); //set_time_window_adjustment(tab, time_window); + time_change_manager(tab, time_window); + + +#if 0 /* Set scrollbar */ LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context); TimeInterval time_span = tsc->time_span; GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(tab->scrollbar)); - g_object_set(G_OBJECT(adjustment), "lower", 0.0, /* lower */ @@ -721,6 +724,7 @@ void lttvwindow_report_time_window(Tab *tab, ltt_time_sub(time_window->start_time, time_span.start_time)) * NANOSECONDS_PER_SECOND); +#endif //0 } @@ -733,11 +737,13 @@ void lttvwindow_report_time_window(Tab *tab, */ void lttvwindow_report_current_time(Tab *tab, - const LttTime *time) + LttTime time) { LttvAttributeValue value; LttvHooks * tmp; - tab->current_time = *time; + + current_time_change_manager(tab, time); + g_assert(lttv_iattribute_find_by_path(tab->attributes, "hooks/updatecurrenttime", LTTV_POINTER, &value)); tmp = (LttvHooks*)*(value.v_pointer); diff --git a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h index b4dea0e7..9711f561 100644 --- a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h +++ b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h @@ -559,22 +559,22 @@ void lttvwindow_unregister_dividor(Tab *tab, * Function to set the time interval of the current tab.a * * @param tab the tab the viewer belongs to. - * @param time_interval pointer to the time interval value. + * @param time_interval new time window. */ void lttvwindow_report_time_window(Tab *tab, - const TimeWindow *time_window); + TimeWindow time_window); /** * Function to set the current time/event of the current tab. * It will be called by a viewer's signal handle associated with * the button-release-event signal * @param tab the tab the viewer belongs to. - * @param time a pointer where time is stored. + * @param new current time. */ void lttvwindow_report_current_time(Tab *tab, - const LttTime *time); + LttTime time); /** diff --git a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/mainwindow-private.h b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/mainwindow-private.h index 1f2edf2c..03a2726c 100644 --- a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/mainwindow-private.h +++ b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/mainwindow-private.h @@ -73,15 +73,36 @@ struct _Tab{ //GtkWidget *multivpaned; GtkWidget *viewer_container; GtkWidget *scrollbar; + + /* time bar */ + GtkWidget *MTimebar; + GtkWidget *MText1; + GtkWidget *MEntry1; + GtkWidget *MText2; + GtkWidget *MEntry2; + GtkWidget *MText3a; + GtkWidget *MText3b; + GtkWidget *MEntry3; + GtkWidget *MText4; + GtkWidget *MEntry4; + GtkWidget *MText5a; + GtkWidget *MText5b; + GtkWidget *MEntry5; + GtkWidget *MText6; + GtkWidget *MEntry6; + GtkWidget *MText7; // startTime is the left of the visible area. Corresponds to the scrollbar // value. // Time_Width is a zoom dependant value (corresponding to page size) TimeWindow time_window; + gboolean time_manager_lock; // The current time is the time selected in the visible area by the user, // not the scrollbar value. LttTime current_time; + gboolean current_time_manager_lock; + LttvIAttribute * attributes; //struct _Tab * next; diff --git a/ltt/branches/poly/lttv/modules/gui/lttvwindow/pixmaps/Makefile.am b/ltt/branches/poly/lttv/modules/gui/lttvwindow/pixmaps/Makefile.am index 4cde1ff3..afca17b9 100644 --- a/ltt/branches/poly/lttv/modules/gui/lttvwindow/pixmaps/Makefile.am +++ b/ltt/branches/poly/lttv/modules/gui/lttvwindow/pixmaps/Makefile.am @@ -25,4 +25,5 @@ EXTRA_DIST = \ stock_stop_24.png\ stock_redo_24.png\ stock_refresh_24.png\ - close.png + close.png\ + stock_jump_to_24.png diff --git a/ltt/branches/poly/lttv/modules/gui/lttvwindow/pixmaps/stock_jump_to_24.png b/ltt/branches/poly/lttv/modules/gui/lttvwindow/pixmaps/stock_jump_to_24.png new file mode 100644 index 0000000000000000000000000000000000000000..52f7f60a9ae8b134bd573d4e7d5ba1c243deaee0 GIT binary patch literal 1097 zcmV-P1h)H$P)}=K~jd^H78%fhrEcK*)V4{Er+poRD&&o5T?P~~nSgxW{-%VUQ~|b9>;X=OXNB|*u=jQmkz3JEqvz!8 z&n?mS%Yc0JLR`Lmu~sgB|EP@o@R+nV)yeV0c66s@#oGd_6%brWb)(RjhJkIxv2BZ? z>?HvH7`Q^?-Z%KHX&VO))KOA-AC_gJwPJo|gqfKI_4U8NC-UggiSr?II4}xHo2SFexfsxc0=bL}!!s$Jj?sc#2!~0vZg_j3mdn@NO5Uj_zc8eF?=i3Gf91K>{HN1m71j zOI{=@2AC@fF8Xo0J#BtL%K%ZZmBsMOyJAw!(9_7tsX`Q+IwandU9tO z#pOk$GaeE^X3=MID#zIP663#5aj2yq;7i~D2Ia!t?xMrIZ_sTUmg`1!o_^LEy*@EN8;7bcL3u3rEF2!3@a