X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Fmodules%2Fgui%2Fcontrolflow%2Fdrawing.c;h=375ed57007780e053deb0716bed976c93a1d69bb;hb=a00149f6aeb2c16c4911e6df31ed94d398b768bd;hp=9092f9585314dbb4629e5f9f64bf3a296c4ec34a;hpb=5ac76b2296e074afbf06358a7ffb1603f8c7593a;p=lttv.git diff --git a/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c b/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c index 9092f958..375ed570 100644 --- a/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c +++ b/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c @@ -21,13 +21,14 @@ #include #include -#include +#include +#include #include #include "drawing.h" +#include "eventhooks.h" #include "cfv.h" #include "cfv-private.h" -#include "eventhooks.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) @@ -66,7 +67,7 @@ static GdkColor CF_Colors [] = /* Function responsible for updating the exposed area. - * It must call processTrace() to ask for this update. + * It must do an events request to the lttvwindow API to ask for this update. * Note : this function cannot clear the background, because it may * erase drawing already present (SAFETY). */ @@ -78,93 +79,155 @@ void drawing_data_request(Drawing_t *drawing, { 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); + TimeWindow time_window = + lttvwindow_get_time_window(drawing->control_flow_data->tab); - g_debug("req : window_end : %u, %u", window_end.tv_sec, - window_end.tv_nsec); + ControlFlowData *control_flow_data = drawing->control_flow_data; + Tab *tab = control_flow_data->tab; + // (ControlFlowData*)g_object_get_data( + // G_OBJECT(drawing->drawing_area), "control_flow_data"); + + LttTime start, time_end; + LttTime window_end = ltt_time_add(time_window.time_width, + time_window.start_time); - g_debug("req : time width : %u, %u", control_flow_data->time_window.time_width.tv_sec, - control_flow_data->time_window.time_width.tv_nsec); + g_debug("req : window start_time : %u, %u", time_window.start_time.tv_sec, + time_window.start_time.tv_nsec); + + g_debug("req : window time width : %u, %u", time_window.time_width.tv_sec, + time_window.time_width.tv_nsec); + g_debug("req : window_end : %u, %u", window_end.tv_sec, + window_end.tv_nsec); + g_debug("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, + 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); - LttvTracesetState * tss = - (LttvTracesetState*)tsc; - - //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_debug("req : start : %u, %u", event_request.time_begin.tv_sec, - event_request.time_begin.tv_nsec); - - g_debug("req : end : %u, %u", event_request.time_end.tv_sec, - event_request.time_end.tv_nsec); + convert_pixels_to_time(drawing->drawing_area->allocation.width, x+width, + time_window.start_time, + window_end, + &time_end); + EventsRequest *events_request = g_new(EventsRequest, 1); + // Create the hooks 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); - lttv_state_traceset_seek_time_closest(tss, 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, NULL, 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, NULL, 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); + LttvHooks *before_chunk_traceset = lttv_hooks_new(); + LttvHooks *after_chunk_traceset = lttv_hooks_new(); + + lttv_hooks_add(before_chunk_traceset, + before_data_request, + events_request, + LTTV_PRIO_DEFAULT); + + lttv_hooks_add(after_chunk_traceset, + after_data_request, + events_request, + LTTV_PRIO_DEFAULT); + lttv_hooks_add(event, + draw_event_hook, + events_request, + LTTV_PRIO_STATE-5); + lttv_hooks_add(event, + draw_after_hook, + events_request, + LTTV_PRIO_STATE+5); + + + // Fill the events request + events_request->owner = control_flow_data; + events_request->viewer_data = control_flow_data; + events_request->servicing = FALSE; + events_request->start_time = start; + events_request->start_position = NULL; + events_request->stop_flag = FALSE; + events_request->end_time = time_end; + events_request->num_events = G_MAXUINT; + events_request->end_position = NULL; + events_request->before_chunk_traceset = before_chunk_traceset; + events_request->before_chunk_trace = NULL; + events_request->before_chunk_tracefile = NULL; + events_request->event = event; + events_request->event_by_id = NULL; + events_request->after_chunk_tracefile = NULL; + events_request->after_chunk_trace = NULL; + events_request->after_chunk_traceset = after_chunk_traceset; + events_request->before_request = NULL; + events_request->after_request = NULL; + + g_debug("req : start : %u, %u", start.tv_sec, + start.tv_nsec); + + g_debug("req : end : %u, %u", time_end.tv_sec, + time_end.tv_nsec); + + lttvwindow_events_request_remove_all(tab, + control_flow_data); + lttvwindow_events_request(tab, events_request); +} + + +void drawing_data_request_begin(EventsRequest *events_request, LttvTracesetState *tss) +{ + g_debug("Begin of data request chunk"); + ControlFlowData *cfd = events_request->viewer_data; + LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tss); + + LttTime current_time = lttv_traceset_context_get_current_tfc(tsc)->timestamp; + + cfd->drawing->last_start = current_time; +} + +void drawing_data_request_end(EventsRequest *events_request, LttvTracesetState *tss) +{ + gint x, x_end, width; + + ControlFlowData *cfd = events_request->viewer_data; + LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tss); + Drawing_t *drawing = cfd->drawing; + + TimeWindow time_window = + lttvwindow_get_time_window(cfd->tab); + + g_debug("End of data request chunk"); + LttTime window_end = ltt_time_add(time_window.time_width, + time_window.start_time); + + LttTime current_time = lttv_traceset_context_get_current_tfc(tsc)->timestamp; + + convert_time_to_pixels( + time_window.start_time, + window_end, + cfd->drawing->last_start, + drawing->width, + &x); + + convert_time_to_pixels( + time_window.start_time, + window_end, + current_time, + drawing->width, + &x_end); + + width = x_end - x; + + drawing->damage_begin = x+width; + drawing->damage_end = drawing->width; + + /* ask for the buffer to be redrawn */ + gtk_widget_queue_draw_area ( drawing->drawing_area, + x, 0, + width, drawing->height); + } - + + /* Callbacks */ @@ -184,8 +247,8 @@ configure_event( GtkWidget *widget, GdkEventConfigure *event, * has updated the time interval before this configure gets * executed. */ - get_time_window(drawing->control_flow_data->mw, - &drawing->control_flow_data->time_window); + //lttvwindow_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, @@ -194,7 +257,8 @@ configure_event( GtkWidget *widget, GdkEventConfigure *event, // -1); g_debug("drawing configure event"); - g_debug("New draw size : %i by %i",widget->allocation.width, widget->allocation.height); + g_debug("New draw size : %i by %i",widget->allocation.width, + widget->allocation.height); if (drawing->pixmap) @@ -226,77 +290,31 @@ configure_event( GtkWidget *widget, GdkEventConfigure *event, /* Initial data request */ + /* no, do initial data request in the expose event */ // Do not need to ask for data of 1 pixel : not synchronized with // main window time at this moment. - drawing_data_request(drawing, &drawing->pixmap, 0, 0, - widget->allocation.width, - widget->allocation.height); + //drawing_data_request(drawing, &drawing->pixmap, 0, 0, + // widget->allocation.width, + // widget->allocation.height); drawing->width = widget->allocation.width; drawing->height = widget->allocation.height; - + + drawing->damage_begin = 0; + drawing->damage_end = widget->allocation.width; + + if(drawing->damage_begin < drawing->damage_end) + { + drawing_data_request(drawing, + &drawing->pixmap, + drawing->damage_begin, + 0, + drawing->damage_end, + 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->black_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->black_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->black_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->black_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 } @@ -305,27 +323,31 @@ 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_debug("drawing expose event"); - - guint x=0; - LttTime* current_time = - guicontrolflow_get_current_time(control_flow_data); + TimeWindow time_window = + lttvwindow_get_time_window(control_flow_data->tab); + LttTime current_time = + lttvwindow_get_current_time(control_flow_data->tab); - LttTime window_end = ltt_time_add(control_flow_data->time_window.time_width, - control_flow_data->time_window.start_time); + guint cursor_x=0; + + LttTime window_end = ltt_time_add(time_window.time_width, + time_window.start_time); convert_time_to_pixels( - control_flow_data->time_window.start_time, + time_window.start_time, window_end, - *current_time, + current_time, widget->allocation.width, - &x); - + &cursor_x); + + + /* update the screen from the pixmap buffer */ gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], drawing->pixmap, @@ -333,29 +355,44 @@ expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data ) event->area.x, event->area.y, event->area.width, event->area.height); - if(x >= event->area.x && x <= event->area.x+event->area.width) - { + + /* Draw the dotted lines */ + + if(drawing->dotted_gc == NULL) { + + drawing->dotted_gc = gdk_gc_new(drawing->drawing_area->window); + gdk_gc_copy(drawing->dotted_gc, widget->style->white_gc); + gint8 dash_list[] = { 1, 2 }; - GdkGC *gc = gdk_gc_new(control_flow_data->drawing->pixmap); - gdk_gc_copy(gc, widget->style->white_gc); - gdk_gc_set_line_attributes(gc, + gdk_gc_set_line_attributes(drawing->dotted_gc, 1, GDK_LINE_ON_OFF_DASH, GDK_CAP_BUTT, GDK_JOIN_MITER); - gdk_gc_set_dashes(gc, + gdk_gc_set_dashes(drawing->dotted_gc, 0, dash_list, 2); drawing_draw_line(NULL, widget->window, - x, event->area.y, - x, event->area.y+event->area.height, - gc); - gdk_gc_unref(gc); + cursor_x, 0, + cursor_x, drawing->height, + drawing->dotted_gc); } return FALSE; } +static gboolean +after_expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data ) +{ + //g_assert(0); + g_critical("AFTER EXPOSE"); + + return FALSE; + + +} + + /* mouse click */ static gboolean button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer user_data ) @@ -365,31 +402,33 @@ button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer user_data G_OBJECT(widget), "control_flow_data"); Drawing_t *drawing = control_flow_data->drawing; - + TimeWindow time_window = + lttvwindow_get_time_window(control_flow_data->tab); g_debug("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); + LttTime window_end = ltt_time_add(time_window.time_width, + time_window.start_time); /* left mouse button click */ g_debug("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_window.start_time, + window_end, &time); - set_current_time(control_flow_data->mw, &time); + lttvwindow_report_current_time(control_flow_data->tab, &time); } - set_focused_pane(control_flow_data->mw, gtk_widget_get_parent(control_flow_data->scrolled_window)); - + lttvwindow_report_focus(control_flow_data->tab, + gtk_widget_get_parent(guicontrolflow_get_widget(control_flow_data))); + return FALSE; } @@ -415,6 +454,15 @@ Drawing_t *drawing_construct(ControlFlowData *control_flow_data) drawing->pango_layout = gtk_widget_create_pango_layout(drawing->drawing_area, NULL); + + drawing->dotted_gc = NULL; + + drawing->height = 0; + drawing->width = 0; + drawing->depth = 0; + + drawing->damage_begin = 0; + drawing->damage_end = 0; //gtk_widget_set_size_request(drawing->drawing_area->window, 50, 50); g_object_set_data_full( @@ -477,6 +525,11 @@ Drawing_t *drawing_construct(ControlFlowData *control_flow_data) G_CALLBACK (expose_event), (gpointer)drawing); + g_signal_connect_after (G_OBJECT(drawing->drawing_area), + "expose_event", + G_CALLBACK (after_expose_event), + (gpointer)drawing); + g_signal_connect (G_OBJECT(drawing->drawing_area), "button-press-event", G_CALLBACK (button_press_event), @@ -491,12 +544,14 @@ Drawing_t *drawing_construct(ControlFlowData *control_flow_data) void drawing_destroy(Drawing_t *drawing) { - + g_info("drawing_destroy %p", 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); + if(!drawing->dotted_gc) gdk_gc_unref(drawing->dotted_gc); g_free(drawing); + g_info("drawing_destroy end"); } GtkWidget *drawing_get_drawing_area(Drawing_t *drawing) @@ -516,16 +571,16 @@ GtkWidget *drawing_get_widget(Drawing_t *drawing) void convert_pixels_to_time( gint width, guint x, - LttTime *window_time_begin, - LttTime *window_time_end, + 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); + 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); + *time = ltt_time_add(window_time_begin, *time); } @@ -551,31 +606,6 @@ void convert_time_to_pixels( } -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, @@ -736,7 +766,7 @@ static gboolean expose_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data ) { Drawing_t *drawing = (Drawing_t*)user_data; - + TimeWindow time_window = lttvwindow_get_time_window(drawing->control_flow_data->tab); gchar text[255]; PangoContext *context; @@ -750,13 +780,13 @@ expose_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data ) GdkColor background = { 0, 0xffff, 0xffff, 0xffff }; LttTime window_end = - ltt_time_add(drawing->control_flow_data->time_window.time_width, - drawing->control_flow_data->time_window.start_time); + ltt_time_add(time_window.time_width, + time_window.start_time); LttTime half_width = - ltt_time_div(drawing->control_flow_data->time_window.time_width,2.0); + ltt_time_div(time_window.time_width,2.0); LttTime window_middle = ltt_time_add(half_width, - drawing->control_flow_data->time_window.start_time); + time_window.start_time); g_debug("ruler expose event"); gdk_draw_rectangle (drawing->ruler->window, @@ -780,8 +810,8 @@ expose_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data ) snprintf(text, 255, "%lus\n%luns", - drawing->control_flow_data->time_window.start_time.tv_sec, - drawing->control_flow_data->time_window.start_time.tv_nsec); + time_window.start_time.tv_sec, + time_window.start_time.tv_nsec); layout = gtk_widget_create_pango_layout(drawing->drawing_area, NULL);