X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Fmodules%2Fgui%2Fcontrolflow%2Fdrawing.c;h=acaf0a4230541954bec6a2ea1008e225718c72bc;hb=224446ce9bb1b6724122cfdf4e3e716a5526af24;hp=8ed214a3ba3d422fa135cd916d2b55371116b190;hpb=88feb618dc79481733516a77f285bb6514bb1d17;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 8ed214a3..acaf0a42 100644 --- a/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c +++ b/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c @@ -1,9 +1,28 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Mathieu Desnoyers + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ #include #include -#include -#include +#include +#include +#include +#include #include #include "drawing.h" @@ -18,6 +37,13 @@ * drawing functions * *****************************************************************************/ +static gboolean +expose_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data ); + +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 { @@ -53,43 +79,39 @@ void drawing_data_request(Drawing_t *drawing, { if(width < 0) return ; if(height < 0) return ; + + const TimeWindow *time_window = lttvwindow_get_time_window(drawing->control_flow_data->mw); + ControlFlowData *control_flow_data = (ControlFlowData*)g_object_get_data( - G_OBJECT( - drawing->drawing_area), - "control_flow_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); + LttTime window_end = ltt_time_add(time_window->time_width, + time_window->start_time); - g_critical("req : window_end : %u, %u", window_end.tv_sec, - window_end.tv_nsec); + g_debug("req : window_end : %u, %u", window_end.tv_sec, + window_end.tv_nsec); - g_critical("req : time width : %u, %u", control_flow_data->time_window.time_width.tv_sec, - control_flow_data->time_window.time_width.tv_nsec); + g_debug("req : time width : %u, %u", time_window->time_width.tv_sec, + time_window->time_width.tv_nsec); - g_critical("x is : %i, x+width is : %i", x, x+width); + 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, + time_window->start_time, + window_end, &end); LttvTracesetContext * tsc = - get_traceset_context(control_flow_data->mw); - - //send_test_process( - //guicontrolflow_get_process_list(drawing->control_flow_data), - //drawing); - //send_test_drawing( - //guicontrolflow_get_process_list(drawing->control_flow_data), - //drawing, *pixmap, x, y, width, height); + lttvwindow_get_traceset_context(control_flow_data->mw); + LttvTracesetState * tss = + (LttvTracesetState*)tsc; // Let's call processTrace() !! EventRequest event_request; // Variable freed at the end of the function. @@ -99,10 +121,10 @@ void drawing_data_request(Drawing_t *drawing, event_request.x_begin = x; event_request.x_end = x+width; - g_critical("req : start : %u, %u", event_request.time_begin.tv_sec, + g_debug("req : start : %u, %u", event_request.time_begin.tv_sec, event_request.time_begin.tv_nsec); - g_critical("req : end : %u, %u", event_request.time_end.tv_sec, + g_debug("req : end : %u, %u", event_request.time_end.tv_sec, event_request.time_end.tv_nsec); LttvHooks *event = lttv_hooks_new(); @@ -111,24 +133,25 @@ void drawing_data_request(Drawing_t *drawing, 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_state_add_event_hooks(tsc); lttv_hooks_add(after_event, draw_after_hook, &event_request); - lttv_process_traceset_seek_time(tsc, start); + //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, after_traceset, NULL, event, after_event); + 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, after_traceset, NULL, event, after_event); + 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_state_remove_event_hooks(tsc); lttv_hooks_destroy(after_traceset); lttv_hooks_destroy(event); @@ -156,8 +179,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, @@ -165,8 +188,8 @@ configure_event( GtkWidget *widget, GdkEventConfigure *event, // widget->allocation.height + SAFETY, // -1); - g_critical("drawing configure event"); - g_critical("New draw size : %i by %i",widget->allocation.width, widget->allocation.height); + g_debug("drawing configure event"); + g_debug("New draw size : %i by %i",widget->allocation.width, widget->allocation.height); if (drawing->pixmap) @@ -188,7 +211,7 @@ configure_event( GtkWidget *widget, GdkEventConfigure *event, // Clear the image gdk_draw_rectangle (drawing->pixmap, - widget->style->white_gc, + widget->style->black_gc, TRUE, 0, 0, widget->allocation.width+SAFETY, @@ -223,7 +246,7 @@ configure_event( GtkWidget *widget, GdkEventConfigure *event, /* Copy old data to new pixmap */ gdk_draw_drawable (pixmap, - widget->style->white_gc, + widget->style->black_gc, drawing->pixmap, 0, 0, 0, 0, @@ -236,7 +259,7 @@ configure_event( GtkWidget *widget, GdkEventConfigure *event, // Clear the bottom part of the image (SAFETY) gdk_draw_rectangle (pixmap, - widget->style->white_gc, + widget->style->black_gc, TRUE, 0, drawing->height+SAFETY, drawing->width+SAFETY, // do not overlap @@ -244,7 +267,7 @@ configure_event( GtkWidget *widget, GdkEventConfigure *event, // Clear the right part of the image (SAFETY) gdk_draw_rectangle (pixmap, - widget->style->white_gc, + widget->style->black_gc, TRUE, drawing->width+SAFETY, 0, (widget->allocation.width) - drawing->width, // do not overlap @@ -252,7 +275,7 @@ configure_event( GtkWidget *widget, GdkEventConfigure *event, /* Clear the backgound for data request, but not SAFETY */ gdk_draw_rectangle (pixmap, - drawing->drawing_area->style->white_gc, + drawing->drawing_area->style->black_gc, TRUE, drawing->width + SAFETY, 0, widget->allocation.width - drawing->width, // do not overlap @@ -277,22 +300,24 @@ static gboolean expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data ) { Drawing_t *drawing = (Drawing_t*)user_data; + const TimeWindow *time_window = lttvwindow_get_time_window(drawing->control_flow_data->mw); + const LttTime* current_time = + lttvwindow_get_current_time(drawing->control_flow_data->mw); + ControlFlowData *control_flow_data = (ControlFlowData*)g_object_get_data( G_OBJECT(widget), "control_flow_data"); - g_critical("drawing expose event"); + g_debug("drawing expose event"); guint x=0; - LttTime* current_time = - guicontrolflow_get_current_time(control_flow_data); - LttTime window_end = ltt_time_add(control_flow_data->time_window.time_width, - control_flow_data->time_window.start_time); + 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, widget->allocation.width, @@ -307,9 +332,18 @@ expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data ) if(x >= event->area.x && x <= event->area.x+event->area.width) { + gint8 dash_list[] = { 1, 2 }; GdkGC *gc = gdk_gc_new(control_flow_data->drawing->pixmap); - gdk_gc_copy(gc, widget->style->black_gc); - + gdk_gc_copy(gc, widget->style->white_gc); + gdk_gc_set_line_attributes(gc, + 1, + GDK_LINE_ON_OFF_DASH, + GDK_CAP_BUTT, + GDK_JOIN_MITER); + gdk_gc_set_dashes(gc, + 0, + dash_list, + 2); drawing_draw_line(NULL, widget->window, x, event->area.y, x, event->area.y+event->area.height, @@ -328,28 +362,30 @@ button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer user_data G_OBJECT(widget), "control_flow_data"); Drawing_t *drawing = control_flow_data->drawing; + const TimeWindow *time_window = lttvwindow_get_time_window(drawing->control_flow_data->mw); - - g_critical("click"); + 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_critical("x click is : %f", event->x); + 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->mw, &time); } + + lttvwindow_report_focus(control_flow_data->mw, gtk_widget_get_parent(control_flow_data->scrolled_window)); return FALSE; } @@ -360,10 +396,20 @@ button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer user_data Drawing_t *drawing_construct(ControlFlowData *control_flow_data) { Drawing_t *drawing = g_new(Drawing_t, 1); - - drawing->drawing_area = gtk_drawing_area_new (); + drawing->control_flow_data = control_flow_data; + drawing->vbox = gtk_vbox_new(FALSE, 1); + drawing->ruler = gtk_drawing_area_new (); + gtk_widget_set_size_request(drawing->ruler, -1, 27); + + drawing->drawing_area = gtk_drawing_area_new (); + + gtk_box_pack_start(GTK_BOX(drawing->vbox), drawing->ruler, + FALSE, FALSE, 0); + gtk_box_pack_end(GTK_BOX(drawing->vbox), drawing->drawing_area, + TRUE, TRUE, 0); + drawing->pango_layout = gtk_widget_create_pango_layout(drawing->drawing_area, NULL); @@ -374,6 +420,12 @@ Drawing_t *drawing_construct(ControlFlowData *control_flow_data) drawing, (GDestroyNotify)drawing_destroy); + g_object_set_data( + G_OBJECT(drawing->ruler), + "drawing", + drawing); + + //gtk_widget_modify_bg( drawing->drawing_area, // GTK_STATE_NORMAL, // &CF_Colors[BLACK]); @@ -403,7 +455,20 @@ Drawing_t *drawing_construct(ControlFlowData *control_flow_data) "configure_event", G_CALLBACK (configure_event), (gpointer)drawing); - + + g_signal_connect (G_OBJECT(drawing->ruler), + "expose_event", + G_CALLBACK(expose_ruler), + (gpointer)drawing); + + gtk_widget_add_events(drawing->ruler, GDK_POINTER_MOTION_MASK); + + g_signal_connect (G_OBJECT(drawing->ruler), + "motion-notify-event", + G_CALLBACK(motion_notify_ruler), + (gpointer)drawing); + + g_signal_connect (G_OBJECT(drawing->drawing_area), "expose_event", G_CALLBACK (expose_event), @@ -413,7 +478,10 @@ Drawing_t *drawing_construct(ControlFlowData *control_flow_data) "button-press-event", G_CALLBACK (button_press_event), (gpointer)drawing); - + + gtk_widget_show(drawing->ruler); + gtk_widget_show(drawing->drawing_area); + return drawing; } @@ -428,11 +496,16 @@ void drawing_destroy(Drawing_t *drawing) g_free(drawing); } -GtkWidget *drawing_get_widget(Drawing_t *drawing) +GtkWidget *drawing_get_drawing_area(Drawing_t *drawing) { return drawing->drawing_area; } +GtkWidget *drawing_get_widget(Drawing_t *drawing) +{ + return drawing->vbox; +} + /* convert_pixels_to_time * * Convert from window pixel and time interval to an absolute time. @@ -440,16 +513,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); } @@ -554,7 +627,7 @@ void drawing_insert_square(Drawing_t *drawing, /* add an empty square */ gdk_draw_rectangle (pixmap, - drawing->drawing_area->style->white_gc, + drawing->drawing_area->style->black_gc, TRUE, 0, y, drawing->width + SAFETY, // do not overlap @@ -637,4 +710,176 @@ void drawing_remove_square(Drawing_t *drawing, //gtk_widget_draw( drawing->drawing_area, &update_rect); } +void drawing_update_ruler(Drawing_t *drawing, TimeWindow *time_window) +{ + GtkRequisition req; + GdkRectangle rect; + + req.width = drawing->ruler->allocation.width; + req.height = drawing->ruler->allocation.height; + + + rect.x = 0; + rect.y = 0; + rect.width = req.width; + rect.height = req.height; + + gtk_widget_queue_draw(drawing->ruler); + //gtk_widget_draw( drawing->ruler, &rect); +} + +/* Redraw the ruler */ +static gboolean +expose_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data ) +{ + Drawing_t *drawing = (Drawing_t*)user_data; + const TimeWindow *time_window = lttvwindow_get_time_window(drawing->control_flow_data->mw); + gchar text[255]; + + PangoContext *context; + PangoLayout *layout; + PangoAttribute *attribute; + PangoFontDescription *FontDesc; + gint Font_Size; + PangoRectangle ink_rect; + guint global_width=0; + GdkColor foreground = { 0, 0, 0, 0 }; + GdkColor background = { 0, 0xffff, 0xffff, 0xffff }; + + LttTime window_end = + ltt_time_add(time_window->time_width, + time_window->start_time); + LttTime half_width = + ltt_time_div(time_window->time_width,2.0); + LttTime window_middle = + ltt_time_add(half_width, + time_window->start_time); + g_debug("ruler expose event"); + + gdk_draw_rectangle (drawing->ruler->window, + drawing->ruler->style->white_gc, + TRUE, + event->area.x, event->area.y, + event->area.width, + event->area.height); + + GdkGC *gc = gdk_gc_new(drawing->ruler->window); + gdk_gc_copy(gc, drawing->ruler->style->black_gc); + gdk_gc_set_line_attributes(gc, + 2, + GDK_LINE_SOLID, + GDK_CAP_BUTT, + GDK_JOIN_MITER); + gdk_draw_line (drawing->ruler->window, + gc, + event->area.x, 1, + event->area.x + event->area.width, 1); + + + snprintf(text, 255, "%lus\n%luns", + time_window->start_time.tv_sec, + time_window->start_time.tv_nsec); + + layout = gtk_widget_create_pango_layout(drawing->drawing_area, NULL); + + context = pango_layout_get_context(layout); + FontDesc = pango_context_get_font_description(context); + + pango_font_description_set_size(FontDesc, 6*PANGO_SCALE); + pango_layout_context_changed(layout); + + pango_layout_set_text(layout, text, -1); + pango_layout_get_pixel_extents(layout, &ink_rect, NULL); + global_width += ink_rect.width; + + gdk_draw_layout_with_colors(drawing->ruler->window, + gc, + 0, + 6, + layout, &foreground, &background); + + gdk_gc_set_line_attributes(gc, + 2, + GDK_LINE_SOLID, + GDK_CAP_ROUND, + GDK_JOIN_ROUND); + + gdk_draw_line (drawing->ruler->window, + gc, + 1, 1, + 1, 7); + + + snprintf(text, 255, "%lus\n%luns", window_end.tv_sec, + window_end.tv_nsec); + + pango_layout_set_text(layout, text, -1); + pango_layout_get_pixel_extents(layout, &ink_rect, NULL); + global_width += ink_rect.width; + + if(global_width <= drawing->ruler->allocation.width) + { + gdk_draw_layout_with_colors(drawing->ruler->window, + gc, + drawing->ruler->allocation.width - ink_rect.width, + 6, + layout, &foreground, &background); + + gdk_gc_set_line_attributes(gc, + 2, + GDK_LINE_SOLID, + GDK_CAP_ROUND, + GDK_JOIN_ROUND); + + gdk_draw_line (drawing->ruler->window, + gc, + drawing->ruler->allocation.width-1, 1, + drawing->ruler->allocation.width-1, 7); + } + + + snprintf(text, 255, "%lus\n%luns", window_middle.tv_sec, + window_middle.tv_nsec); + + pango_layout_set_text(layout, text, -1); + pango_layout_get_pixel_extents(layout, &ink_rect, NULL); + global_width += ink_rect.width; + + if(global_width <= drawing->ruler->allocation.width) + { + gdk_draw_layout_with_colors(drawing->ruler->window, + gc, + (drawing->ruler->allocation.width - ink_rect.width)/2, + 6, + layout, &foreground, &background); + + gdk_gc_set_line_attributes(gc, + 2, + GDK_LINE_SOLID, + GDK_CAP_ROUND, + GDK_JOIN_ROUND); + + gdk_draw_line (drawing->ruler->window, + gc, + drawing->ruler->allocation.width/2, 1, + drawing->ruler->allocation.width/2, 7); + + + + + } + + gdk_gc_unref(gc); + g_object_unref(layout); + + return FALSE; +} + +/* notify mouse on ruler */ +static gboolean +motion_notify_ruler(GtkWidget *widget, GdkEventMotion *event, gpointer user_data) +{ + //g_debug("motion"); + //eventually follow mouse and show time here +}