1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2006 Parisa heidari (inspired from CFV by Mathieu Desnoyers)
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27 #include <ltt/trace.h>
29 #include <lttv/lttv.h>
30 #include <lttv/tracecontext.h>
31 #include <lttvwindow/lttvwindow.h>
32 #include <lttv/state.h>
33 #include <lttv/hook.h>
35 #include "histodrawing.h"
36 #include "histoeventhooks.h"
40 #define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
43 #define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
47 // fixed #define TRACE_NUMBER 0
48 #define EXTRA_ALLOC 1024 // pixels
49 #define padding_width 50
51 #if 0 /* colors for two lines representation */
52 GdkColor histo_drawing_colors
[NUM_COLORS
] =
53 { /* Pixel, R, G, B */
54 { 0, 0, 0, 0 }, /* COL_BLACK */
55 { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_WHITE */
56 { 0, 0x0FFF, 0xFFFF, 0xFFFF }, /* COL_WAIT_FORK : pale blue */
57 { 0, 0xFFFF, 0xFFFF, 0x0000 }, /* COL_WAIT_CPU : yellow */
58 { 0, 0xFFFF, 0xA000, 0xFCFF }, /* COL_EXIT : pale magenta */
59 { 0, 0xFFFF, 0x0000, 0xFFFF }, /* COL_ZOMBIE : purple */
60 { 0, 0xFFFF, 0x0000, 0x0000 }, /* COL_WAIT : red */
61 { 0, 0x0000, 0xFFFF, 0x0000 }, /* COL_RUN : green */
62 { 0, 0x8800, 0xFFFF, 0x8A00 }, /* COL_USER_MODE : pale green */
63 { 0, 0x09FF, 0x01FF, 0xFFFF }, /* COL_SYSCALL : blue */
64 { 0, 0xF900, 0x4200, 0xFF00 }, /* COL_TRAP : pale purple */
65 { 0, 0xFFFF, 0x5AFF, 0x01FF }, /* COL_IRQ : orange */
66 { 0, 0xFFFF, 0xFFFF, 0xFFFF } /* COL_MODE_UNKNOWN : white */
72 GdkColor histo_drawing_colors
[NUM_COLORS
] =
73 { /* Pixel, R, G, B */
74 { 0, 0, 0, 0 }, /* COL_BLACK */
75 { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_WHITE */
76 { 0, 0x0000, 0xFF00, 0x0000 }, /* COL_RUN_USER_MODE : green */
77 { 0, 0x0100, 0x9E00, 0xFFFF }, /* COL_RUN_SYSCALL : pale blue */
78 { 0, 0xFF00, 0xFF00, 0x0100 }, /* COL_RUN_TRAP : yellow */
79 { 0, 0xFFFF, 0x5E00, 0x0000 }, /* COL_RUN_IRQ : red */
80 { 0, 0x6600, 0x0000, 0x0000 }, /* COL_WAIT : dark red */
81 { 0, 0x7700, 0x7700, 0x0000 }, /* COL_WAIT_CPU : dark yellow */
82 { 0, 0x6400, 0x0000, 0x5D00 }, /* COL_ZOMBIE : dark purple */
83 { 0, 0x0700, 0x6400, 0x0000 }, /* COL_WAIT_FORK : dark green */
84 { 0, 0x8900, 0x0000, 0x8400 }, /* COL_EXIT : "less dark" magenta */
85 { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_MODE_UNKNOWN : white */
86 { 0, 0xFFFF, 0xFFFF, 0xFFFF } /* COL_UNNAMED : white */
96 WAIT CPU + WAIT FORK vert foncé ou jaune
105 /*****************************************************************************
106 * drawing functions *
107 *****************************************************************************/
110 histo_expose_ruler( GtkWidget
*widget
, GdkEventExpose
*event
, gpointer user_data
);
113 histo_expose_vertical_ruler( GtkWidget
*widget
, GdkEventExpose
*event
, gpointer user_data
);
116 histo_motion_notify_ruler(GtkWidget
*widget
, GdkEventMotion
*event
, gpointer user_data
);
119 histo_motion_notify_vertical_ruler(GtkWidget
*widget
, GdkEventMotion
*event
, gpointer user_data
);
121 /* Function responsible for updating the exposed area.
122 * It must do an events request to the lttvwindow API to ask for this update.
123 * Note : this function cannot clear the background, because it may
124 * erase drawing already present (SAFETY).
126 void histo_drawing_data_request(histoDrawing_t
*drawing
,
135 void histo_drawing_data_request_begin(EventsRequest
*events_request
, LttvTracesetState
*tss
)
137 g_debug("Begin of data request");
138 HistoControlFlowData
*cfd
= events_request
->viewer_data
;
139 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tss
);
140 TimeWindow time_window
=
141 lttvwindow_get_time_window(cfd
->tab
);
143 guint width
= cfd
->drawing
->width
;
146 cfd
->drawing
->last_start
= events_request
->start_time
;
148 histo_convert_time_to_pixels(
150 events_request
->start_time
,
156 void histo_drawing_chunk_begin(EventsRequest
*events_request
, LttvTracesetState
*tss
)
158 g_debug("Begin of chunk");
159 HistoControlFlowData
*cfd
= events_request
->viewer_data
;
160 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tss
);
162 if(cfd
->chunk_has_begun
) return;
164 cfd
->chunk_has_begun
= TRUE
;
168 void histo_drawing_request_expose(EventsRequest
*events_request
,
169 LttvTracesetState
*tss
,
172 HistoControlFlowData
*cfd
= events_request
->viewer_data
;
173 histoDrawing_t
*drawing
= cfd
->drawing
;
175 guint x
, x_end
, width
;
176 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)tss
;
178 TimeWindow time_window
=
179 lttvwindow_get_time_window(cfd
->tab
);
181 g_debug("histo request expose");
183 histo_convert_time_to_pixels(
188 x
= drawing
->damage_begin
;
192 drawing
->damage_begin
= x
+width
;
195 //changed for histogram:
196 gtk_widget_queue_draw_area ( drawing
->drawing_area
,
199 drawing
->/*drawing_area->allocation.*/height
);
201 // Update directly when scrolling
202 gdk_window_process_updates(drawing
->drawing_area
->window
,
210 /* Create a new backing pixmap of the appropriate size */
211 /* As the scaling will always change, it's of no use to copy old
214 * Change the size if width or height changes.
215 * (different from control flow viewer!)
218 histo_configure_event( GtkWidget
*widget
, GdkEventConfigure
*event
,
221 histoDrawing_t
*drawing
= (histoDrawing_t
*)user_data
;
223 /* First, get the new time interval of the main window */
224 /* we assume (see documentation) that the main window
225 * has updated the time interval before this configure gets
228 //lttvwindow_get_time_window(drawing->histo_control_flow_data->mw,
229 // &drawing->histo_control_flow_data->time_window);
231 /* New pixmap, size of the configure event */
232 //GdkPixmap *pixmap = gdk_pixmap_new(widget->window,
233 // widget->allocation.width + SAFETY,
234 // widget->allocation.height + SAFETY,
236 g_debug("drawing configure event");
237 g_debug("New alloc draw size : %i by %i",widget
->allocation
.width
,
238 widget
->allocation
.height
);
240 /*modified for histogram, if width is not changed, GArray is valid so
241 just redraw, else recalculate all.(event request again)*/
243 //enabled again for histogram:
245 gdk_pixmap_unref(drawing
->pixmap
);
247 drawing
->pixmap
= gdk_pixmap_new(widget
->window
,
248 widget
->allocation
.width
,//+ SAFETY + EXTRA_ALLOC,
249 widget
->allocation
.height
+ EXTRA_ALLOC
,
253 drawing
->alloc_width
= drawing
->width
+ SAFETY
+ EXTRA_ALLOC
;
254 drawing
->alloc_height
= drawing
->height
+ EXTRA_ALLOC
;
256 //drawing->height = widget->allocation.height;
261 // gdk_draw_rectangle (drawing->pixmap,
262 // widget->style->black_gc,
265 // drawing->width+SAFETY,
268 //g_info("init data request");
271 /* Initial data request */
272 /* no, do initial data request in the expose event */
273 // Do not need to ask for data of 1 pixel : not synchronized with
274 // main window time at this moment.
275 //histo_drawing_data_request(drawing, &drawing->pixmap, 0, 0,
276 // widget->allocation.width,
277 // widget->allocation.height);
279 //drawing->width = widget->allocation.width;
280 //drawing->height = widget->allocation.height;
282 drawing
->damage_begin
= 0;
283 drawing
->damage_end
= widget
->allocation
.width
;
285 if((widget
->allocation
.width
!= 1 &&
286 widget
->allocation
.height
!= 1)
287 /*&& drawing->damage_begin < drawing->damage_end */)
290 gdk_draw_rectangle (drawing
->pixmap
,
291 drawing
->drawing_area
->style
->black_gc
,
294 drawing
->drawing_area
->allocation
.width
, drawing
->drawing_area
->allocation
.height
);
295 /* histo_drawing_data_request(drawing,
296 drawing->damage_begin,
298 drawing->damage_end - drawing->damage_begin,
301 //modified for histogram
303 if(widget
->allocation
.width
== drawing
->width
)
306 drawing
->height
= widget
->allocation
.height
;
307 histogram_show( drawing
->histo_control_flow_data
,0,
308 drawing
->histo_control_flow_data
->number_of_process
->len
);
312 drawing
->width
= widget
->allocation
.width
;
313 drawing
->height
= widget
->allocation
.height
;
315 g_array_set_size (drawing
->histo_control_flow_data
->number_of_process
,
316 widget
->allocation
.width
);
317 histo_request_event( drawing
->histo_control_flow_data
,drawing
->damage_begin
318 ,drawing
->damage_end
- drawing
->damage_begin
);
324 /* Redraw the screen from the backing pixmap */
326 histo_expose_event( GtkWidget
*widget
, GdkEventExpose
*event
, gpointer user_data
)
328 histoDrawing_t
*drawing
= (histoDrawing_t
*)user_data
;
330 HistoControlFlowData
*histo_control_flow_data
=
331 (HistoControlFlowData
*)g_object_get_data(
333 "histo_control_flow_data");
335 if(unlikely(drawing
->gc
== NULL
)) {
336 drawing
->gc
= gdk_gc_new(drawing
->drawing_area
->window
);
337 gdk_gc_copy(drawing
->gc
, drawing
->drawing_area
->style
->black_gc
);
340 TimeWindow time_window
=
341 lttvwindow_get_time_window(histo_control_flow_data
->tab
);
342 LttTime current_time
=
343 lttvwindow_get_current_time(histo_control_flow_data
->tab
);
347 LttTime window_end
= time_window
.end_time
;
350 /* update the screen from the pixmap buffer */
351 //added again for histogram:
353 gdk_draw_pixmap(widget
->window
,
354 widget
->style
->fg_gc
[GTK_WIDGET_STATE (widget
)],
356 event
->area
.x
, event
->area
.y
,
357 event
->area
.x
, event
->area
.y
,
358 event
->area
.width
, event
->area
.height
);
361 drawing
->height
= drawing
-> drawing_area
->allocation
.height
;
364 copy_pixmap_to_screen(histo_control_flow_data
->process_list
,
366 widget
->style
->fg_gc
[GTK_WIDGET_STATE (widget
)],
367 event
->area
.x
, event
->area
.y
,
368 event
->area
.width
, event
->area
.height
);
372 /* //disabled for histogram
373 copy_pixmap_to_screen(histo_control_flow_data->process_list,
376 event->area.x, event->area.y,
377 event->area.width, event->area.height);*/
379 /* Erase the dotted lines left.. */
380 if(widget
->allocation
.height
> drawing
->height
)
382 gdk_draw_rectangle (widget
->window
,
383 drawing
->drawing_area
->style
->black_gc
,
385 event
->area
.x
, drawing
->height
,
386 event
->area
.width
, // do not overlap
387 widget
->allocation
.height
- drawing
->height
);
389 if(ltt_time_compare(time_window
.start_time
, current_time
) <= 0 &&
390 ltt_time_compare(window_end
, current_time
) >= 0)
392 /* Draw the dotted lines */
393 histo_convert_time_to_pixels(
400 if(drawing
->dotted_gc
== NULL
) {
402 drawing
->dotted_gc
= gdk_gc_new(drawing
->drawing_area
->window
);
403 gdk_gc_copy(drawing
->dotted_gc
, widget
->style
->white_gc
);
405 gint8 dash_list
[] = { 1, 2 };
406 gdk_gc_set_line_attributes(drawing
->dotted_gc
,
408 GDK_LINE_ON_OFF_DASH
,
411 gdk_gc_set_dashes(drawing
->dotted_gc
,
417 gint height_tot
= MAX(widget
->allocation
.height
, drawing
->height
);
418 gdk_draw_line(widget
->window
,
421 cursor_x
, height_tot
);
428 histo_after_expose_event( GtkWidget
*widget
, GdkEventExpose
*event
, gpointer user_data
)
431 g_debug("AFTER EXPOSE");
438 histo_button_press_event( GtkWidget
*widget
, GdkEventButton
*event
, gpointer user_data
)
440 HistoControlFlowData
*histo_control_flow_data
=
441 (HistoControlFlowData
*)g_object_get_data(
443 "histo_control_flow_data");
444 histoDrawing_t
*drawing
= histo_control_flow_data
->drawing
;
445 TimeWindow time_window
=
446 lttvwindow_get_time_window(histo_control_flow_data
->tab
);
449 if(event
->button
== 1)
453 /* left mouse button click */
454 g_debug("x click is : %f", event
->x
);
456 histo_convert_pixels_to_time(drawing
->width
, (guint
)event
->x
,
460 lttvwindow_report_current_time(histo_control_flow_data
->tab
, time
);
461 ////report event->y for vertical zoom +,-
467 //Viewer's vertical scroll bar is already omitted, not needed for histogram.
469 scrollbar_size_allocate(GtkWidget *widget,
470 GtkAllocation *allocation,
473 histoDrawing_t *drawing = (histoDrawing_t*)user_data;
475 gtk_widget_set_size_request(drawing->padding, allocation->width, -1);
476 //gtk_widget_queue_resize(drawing->padding);
477 //gtk_widget_queue_resize(drawing->ruler);
478 gtk_container_check_resize(GTK_CONTAINER(drawing->ruler_hbox));
484 histoDrawing_t
*histo_drawing_construct(HistoControlFlowData
*histo_control_flow_data
)
486 histoDrawing_t
*drawing
= g_new(histoDrawing_t
, 1);
488 drawing
->histo_control_flow_data
= histo_control_flow_data
;
490 drawing
->vbox
= gtk_vbox_new(FALSE
, 1);
493 drawing
->ruler_hbox
= gtk_hbox_new(FALSE
, 1);
494 drawing
->ruler
= gtk_drawing_area_new ();
495 //gtk_widget_set_size_request(drawing->ruler, -1, 27);
497 drawing
->padding
= gtk_drawing_area_new ();
498 //gtk_widget_set_size_request(drawing->padding, -1, 27);
500 gtk_box_pack_start(GTK_BOX(drawing
->ruler_hbox
), drawing
->padding
,FALSE
, FALSE
, 0);
502 gtk_box_pack_end(GTK_BOX(drawing
->ruler_hbox
), drawing
->ruler
,
505 drawing
->drawing_area
= gtk_drawing_area_new ();
509 ///at this time not necessary for histogram
510 drawing->hbox = gtk_hbox_new(FALSE, 1);
512 drawing->viewport = gtk_viewport_new(NULL, histo_control_flow_data->v_adjust);
513 drawing->scrollbar = gtk_vscrollbar_new(histo_control_flow_data->v_adjust);
514 gtk_box_pack_start(GTK_BOX(drawing->hbox), drawing->viewport,
516 gtk_box_pack_end(GTK_BOX(drawing->hbox), drawing->scrollbar,
518 gtk_container_add(GTK_CONTAINER(drawing->viewport),
519 drawing->drawing_area);*/
521 //add vertical ruler:
522 drawing
->vruler_drawing_hbox
= gtk_hbox_new(FALSE
, 1);
523 drawing
-> vertical_ruler
=gtk_drawing_area_new ();
524 gtk_box_pack_start(GTK_BOX(drawing
->vruler_drawing_hbox
), drawing
->vertical_ruler
,
526 gtk_box_pack_end(GTK_BOX(drawing
->vruler_drawing_hbox
), drawing
->drawing_area
,
528 gtk_widget_set_size_request(drawing
->vertical_ruler
, padding_width
, -1);
530 gtk_box_pack_start(GTK_BOX(drawing
->vbox
), drawing
->ruler_hbox
,
532 gtk_box_pack_end(GTK_BOX(drawing
->vbox
), drawing
->vruler_drawing_hbox
/*drawing_area*/,
535 drawing
->pango_layout
=
536 gtk_widget_create_pango_layout(drawing
->drawing_area
, NULL
);
541 drawing
->alloc_height
= 1;
542 drawing
->alloc_width
= 1;
544 drawing
->damage_begin
= 0;
545 drawing
->damage_end
= 0;
546 drawing
->horizontal_sel
= -1;
548 //gtk_widget_set_size_request(drawing->drawing_area->window, 50, 50);
549 g_object_set_data_full(
550 G_OBJECT(drawing
->drawing_area
),
551 "histo_Link_drawing_Data",
553 (GDestroyNotify
)histo_drawing_destroy
);
556 G_OBJECT(drawing
->ruler
),
561 G_OBJECT(drawing
->vertical_ruler
),
565 //gtk_widget_modify_bg( drawing->drawing_area,
567 // &CF_Colors[BLACK]);
569 //gdk_window_get_geometry(drawing->drawing_area->window,
571 // &(drawing->width),
572 // &(drawing->height),
575 //drawing->pixmap = gdk_pixmap_new(
576 // drawing->drawing_area->window,
581 drawing
->pixmap
= NULL
;
583 // drawing->pixmap = gdk_pixmap_new(drawing->drawing_area->window,
584 // drawing->drawing_area->allocation.width,
585 // drawing->drawing_area->allocation.height,
588 g_signal_connect (G_OBJECT(drawing
->drawing_area
),
590 G_CALLBACK (histo_configure_event
),
593 g_signal_connect (G_OBJECT(drawing
->ruler
),
595 G_CALLBACK(histo_expose_ruler
),
598 gtk_widget_add_events(drawing
->ruler
, GDK_POINTER_MOTION_MASK
);
599 gtk_widget_add_events(drawing
->vertical_ruler
, GDK_POINTER_MOTION_MASK
);
601 g_signal_connect (G_OBJECT(drawing
->ruler
),
602 "motion-notify-event",
603 G_CALLBACK(histo_motion_notify_ruler
),
607 g_signal_connect (G_OBJECT(drawing
->vertical_ruler
),
609 G_CALLBACK(histo_expose_vertical_ruler
),
612 g_signal_connect (G_OBJECT(drawing
->vertical_ruler
),
613 "motion-notify-event",
614 G_CALLBACK(histo_motion_notify_vertical_ruler
),
617 /*//not necessary for historam.
618 g_signal_connect (G_OBJECT(drawing->drawing_area),
620 G_CALLBACK(scrollbar_size_allocate),
621 (gpointer)drawing); */
624 gtk_widget_set_size_request(drawing
->padding
, padding_width
, -1);//use it for vertical ruler
626 g_signal_connect (G_OBJECT(drawing
->drawing_area
),
628 G_CALLBACK (histo_expose_event
),
631 g_signal_connect_after (G_OBJECT(drawing
->drawing_area
),
633 G_CALLBACK (histo_after_expose_event
),
636 g_signal_connect (G_OBJECT(drawing
->drawing_area
),
637 "button-press-event",
638 G_CALLBACK (histo_button_press_event
),
641 gtk_widget_show(drawing
->ruler
);
642 gtk_widget_show(drawing
->padding
);
643 gtk_widget_show(drawing
->ruler_hbox
);
644 gtk_widget_show(drawing
->vertical_ruler
);
645 gtk_widget_show(drawing
->vruler_drawing_hbox
);
646 gtk_widget_show(drawing
->drawing_area
);
648 /// gtk_widget_show(drawing->viewport);
649 /// gtk_widget_show(drawing->scrollbar);
650 /// gtk_widget_show(drawing->hbox);
652 /* Allocate the colors */
653 GdkColormap
* colormap
= gdk_colormap_get_system();
654 gboolean success
[NUM_COLORS
];
655 gdk_colormap_alloc_colors(colormap
, histo_drawing_colors
, NUM_COLORS
, FALSE
,
659 gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(histo_control_flow_data
->tab
)->window
));
661 gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(histo_control_flow_data
->tab
)->window
));
663 gdk_gc_copy(drawing
->gc
,
664 main_window_get_widget(histo_control_flow_data
->tab
)->style
->black_gc
);
665 gdk_gc_copy(drawing
->dotted_gc
,
666 main_window_get_widget(histo_control_flow_data
->tab
)->style
->white_gc
);
668 gint8 dash_list
[] = { 1, 2 };
669 gdk_gc_set_line_attributes(drawing
->dotted_gc
,
671 GDK_LINE_ON_OFF_DASH
,
674 gdk_gc_set_dashes(drawing
->dotted_gc
,
679 drawing
->ruler_gc_butt
=
680 gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(histo_control_flow_data
->tab
)->window
));
681 gdk_gc_copy(drawing
->ruler_gc_butt
,
682 main_window_get_widget(histo_control_flow_data
->tab
)->style
->black_gc
);
683 drawing
->ruler_gc_round
=
684 gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(histo_control_flow_data
->tab
)->window
));
685 gdk_gc_copy(drawing
->ruler_gc_round
,
686 main_window_get_widget(histo_control_flow_data
->tab
)->style
->black_gc
);
689 gdk_gc_set_line_attributes(drawing
->ruler_gc_butt
,
695 gdk_gc_set_line_attributes(drawing
->ruler_gc_round
,
703 void histo_drawing_destroy(histoDrawing_t
*drawing
)
705 g_info("histo_drawing_destroy %p", drawing
);
707 /* Free the colors */
708 GdkColormap
* colormap
= gdk_colormap_get_system();
710 gdk_colormap_free_colors(colormap
, histo_drawing_colors
, NUM_COLORS
);
712 // Do not unref here, histoDrawing_t destroyed by it's widget.
713 //g_object_unref( G_OBJECT(drawing->drawing_area));
714 if(drawing
->gc
!= NULL
)
715 gdk_gc_unref(drawing
->gc
);
717 g_object_unref(drawing
->pango_layout
);
718 if(drawing
->dotted_gc
!= NULL
) gdk_gc_unref(drawing
->dotted_gc
);
719 if(drawing
->ruler_gc_butt
!= NULL
) gdk_gc_unref(drawing
->ruler_gc_butt
);
720 if(drawing
->ruler_gc_round
!= NULL
) gdk_gc_unref(drawing
->ruler_gc_round
);
722 //added for histogram
724 gdk_pixmap_unref(drawing
->pixmap
);
726 g_info("histo_drawing_destroy end");
729 GtkWidget
*histo_drawing_get_drawing_area(histoDrawing_t
*drawing
)
731 return drawing
->drawing_area
;
734 GtkWidget
*histo_drawing_get_widget(histoDrawing_t
*drawing
)
736 return drawing
->vbox
;
739 void histo_drawing_draw_line( histoDrawing_t
*drawing
,
745 gdk_draw_line (pixmap
,
750 void histo_drawing_clear(histoDrawing_t
*drawing
,guint clear_from
,guint clear_to
)
753 HistoControlFlowData
*cfd
= drawing
->histo_control_flow_data
;
754 guint clear_width
= clear_to
- clear_from
;
756 //disabled for histogram
757 rectangle_pixmap(cfd->process_list,
758 drawing->drawing_area->style->black_gc,
761 drawing->alloc_width, // do not overlap
763 //instead, this is added for histogram
765 histo_rectangle_pixmap (drawing
->drawing_area
->style
->black_gc
,
768 clear_width
/*drawing->width*/,
773 /* gdk_draw_rectangle (drawing->pixmap,
774 drawing->drawing_area->style->black_gc,
777 drawing->drawing_area->allocation.width,drawing->drawing_area->allocation.height );
780 /* ask for the buffer to be redrawn */
781 //enabled again for histogram.
782 gtk_widget_queue_draw_area ( drawing
->drawing_area
,
784 clear_width
, drawing
->height
);
785 gdk_window_process_updates(drawing
->drawing_area
->window
,TRUE
);
786 //disabled instead for histogram
787 //gtk_widget_queue_draw ( drawing->drawing_area);
792 /* Insert a square corresponding to a new process in the list */
793 /* Applies to whole drawing->width */
794 void drawing_insert_square(histoDrawing_t
*drawing
,
798 //GdkRectangle update_rect;
799 gboolean reallocate
= FALSE
;
800 GdkPixmap
*new_pixmap
;
802 /* Allocate a new pixmap with new height */
803 if(drawing
->alloc_height
< drawing
->height
+ height
) {
805 new_pixmap
= gdk_pixmap_new(drawing
->drawing_area
->window
,
806 drawing
->width
+ SAFETY
+ EXTRA_ALLOC
,
807 drawing
->height
+ height
+ EXTRA_ALLOC
,
809 drawing
->alloc_width
= drawing
->width
+ SAFETY
+ EXTRA_ALLOC
;
810 drawing
->alloc_height
= drawing
->height
+ height
+ EXTRA_ALLOC
;
813 /* Copy the high region */
814 gdk_draw_pixmap (new_pixmap
,
815 drawing
->drawing_area
->style
->black_gc
,
819 drawing
->width
+ SAFETY
, y
);
822 new_pixmap
= drawing
->pixmap
;
825 //GdkPixmap *pixmap = gdk_pixmap_new(drawing->drawing_area->window,
826 // drawing->width + SAFETY,
827 // drawing->height + height,
830 /* add an empty square */
831 gdk_draw_rectangle (new_pixmap
,
832 drawing
->drawing_area
->style
->black_gc
,
835 drawing
->width
+ SAFETY
, // do not overlap
838 /* copy the bottom of the region */
839 gdk_draw_pixmap (new_pixmap
,
840 drawing
->drawing_area
->style
->black_gc
,
844 drawing
->width
+SAFETY
, drawing
->height
- y
);
847 if(reallocate
&& likely(drawing
->pixmap
)) {
848 gdk_pixmap_unref(drawing
->pixmap
);
849 drawing
->pixmap
= new_pixmap
;
852 if(unlikely(drawing
->height
==1)) drawing
->height
= height
;
853 else drawing
->height
+= height
;
855 gtk_widget_set_size_request(drawing
->drawing_area
,
858 gtk_widget_queue_resize_no_redraw(drawing
->drawing_area
);
860 /* ask for the buffer to be redrawn */
861 gtk_widget_queue_draw_area ( drawing
->drawing_area
,
863 drawing
->width
, drawing
->height
-y
);
867 /* Remove a square corresponding to a removed process in the list */
868 void drawing_remove_square(histoDrawing_t
*drawing
,
874 if(unlikely((guint
)drawing
->height
== height
)) {
875 //pixmap = gdk_pixmap_new(
876 // drawing->drawing_area->window,
877 // drawing->width + SAFETY,
880 pixmap
= drawing
->pixmap
;
883 /* Allocate a new pixmap with new height */
884 //pixmap = gdk_pixmap_new(
885 // drawing->drawing_area->window,
886 // drawing->width + SAFETY,
887 // drawing->height - height,
889 /* Keep the same preallocated pixmap */
890 pixmap
= drawing
->pixmap
;
892 /* Copy the high region */
893 gdk_draw_pixmap (pixmap
,
894 drawing
->drawing_area
->style
->black_gc
,
898 drawing
->width
+ SAFETY
, y
);
900 /* Copy up the bottom of the region */
901 gdk_draw_pixmap (pixmap
,
902 drawing
->drawing_area
->style
->black_gc
,
906 drawing
->width
, drawing
->height
- y
- height
);
908 drawing
->height
-=height
;
911 //if(likely(drawing->pixmap))
912 // gdk_pixmap_unref(drawing->pixmap);
914 //drawing->pixmap = pixmap;
916 gtk_widget_set_size_request(drawing
->drawing_area
,
919 gtk_widget_queue_resize_no_redraw(drawing
->drawing_area
);
920 /* ask for the buffer to be redrawn */
921 gtk_widget_queue_draw_area ( drawing
->drawing_area
,
923 drawing
->width
, MAX(drawing
->height
-y
, 1));
927 void histo_drawing_update_ruler(histoDrawing_t
*drawing
, TimeWindow
*time_window
)
932 req
.width
= drawing
->ruler
->allocation
.width
;
933 req
.height
= drawing
->ruler
->allocation
.height
;
938 rect
.width
= req
.width
;
939 rect
.height
= req
.height
;
941 gtk_widget_queue_draw(drawing
->ruler
);
942 //gtk_widget_draw( drawing->ruler, &rect);
945 /* Redraw the ruler */
947 histo_expose_ruler( GtkWidget
*widget
, GdkEventExpose
*event
, gpointer user_data
)
949 histoDrawing_t
*drawing
= (histoDrawing_t
*)user_data
;
950 TimeWindow time_window
= lttvwindow_get_time_window(drawing
->histo_control_flow_data
->tab
);
953 PangoContext
*context
;
955 PangoFontDescription
*FontDesc
;
956 PangoRectangle ink_rect
;
958 GdkColor foreground
= { 0, 0, 0, 0 };
959 GdkColor background
= { 0, 0xffff, 0xffff, 0xffff };
961 LttTime window_end
= time_window
.end_time
;
963 ltt_time_div(time_window
.time_width
,2.0);
964 LttTime window_middle
=
965 ltt_time_add(half_width
,
966 time_window
.start_time
);
967 g_debug("ruler expose event");
969 gdk_draw_rectangle (drawing
->ruler
->window
,
970 drawing
->ruler
->style
->white_gc
,
972 event
->area
.x
, event
->area
.y
,
976 gdk_draw_line (drawing
->ruler
->window
,
977 drawing
->ruler_gc_butt
,
979 event
->area
.x
+ event
->area
.width
, 1);
982 snprintf(text
, 255, "%lus\n%luns",
983 time_window
.start_time
.tv_sec
,
984 time_window
.start_time
.tv_nsec
);
986 layout
= gtk_widget_create_pango_layout(drawing
->drawing_area
, NULL
);
988 context
= pango_layout_get_context(layout
);
989 FontDesc
= pango_context_get_font_description(context
);
991 pango_font_description_set_size(FontDesc
, 6*PANGO_SCALE
);
992 pango_layout_context_changed(layout
);
994 pango_layout_set_text(layout
, text
, -1);
995 pango_layout_get_pixel_extents(layout
, &ink_rect
, NULL
);
996 global_width
+= ink_rect
.width
;
998 gdk_draw_layout_with_colors(drawing
->ruler
->window
,
999 drawing
->ruler_gc_butt
,
1002 layout
, &foreground
, &background
);
1004 gdk_draw_line (drawing
->ruler
->window
,
1005 drawing
->ruler_gc_round
,
1010 snprintf(text
, 255, "%lus\n%luns", window_end
.tv_sec
,
1011 window_end
.tv_nsec
);
1013 pango_layout_set_text(layout
, text
, -1);
1014 pango_layout_get_pixel_extents(layout
, &ink_rect
, NULL
);
1015 global_width
+= ink_rect
.width
;
1017 if(global_width
<= drawing
->ruler
->allocation
.width
)
1019 gdk_draw_layout_with_colors(drawing
->ruler
->window
,
1020 drawing
->ruler_gc_butt
,
1021 drawing
->ruler
->allocation
.width
- ink_rect
.width
,
1023 layout
, &foreground
, &background
);
1025 gdk_draw_line (drawing
->ruler
->window
,
1026 drawing
->ruler_gc_butt
,
1027 drawing
->ruler
->allocation
.width
-1, 1,
1028 drawing
->ruler
->allocation
.width
-1, 7);
1032 snprintf(text
, 255, "%lus\n%luns", window_middle
.tv_sec
,
1033 window_middle
.tv_nsec
);
1035 pango_layout_set_text(layout
, text
, -1);
1036 pango_layout_get_pixel_extents(layout
, &ink_rect
, NULL
);
1037 global_width
+= ink_rect
.width
;
1039 if(global_width
<= drawing
->ruler
->allocation
.width
)
1041 gdk_draw_layout_with_colors(drawing
->ruler
->window
,
1042 drawing
->ruler_gc_butt
,
1043 (drawing
->ruler
->allocation
.width
- ink_rect
.width
)/2,
1045 layout
, &foreground
, &background
);
1047 gdk_draw_line (drawing
->ruler
->window
,
1048 drawing
->ruler_gc_butt
,
1049 drawing
->ruler
->allocation
.width
/2, 1,
1050 drawing
->ruler
->allocation
.width
/2, 7);
1053 g_object_unref(layout
);
1058 void histo_drawing_update_vertical_ruler(histoDrawing_t
*drawing
)//, TimeWindow *time_window)
1063 req
.width
= drawing
->vertical_ruler
->allocation
.width
;
1064 req
.height
= drawing
->vertical_ruler
->allocation
.height
;
1068 rect
.width
= req
.width
;
1069 rect
.height
= req
.height
;
1071 gtk_widget_queue_draw(drawing
->vertical_ruler
);
1072 //gtk_widget_draw( drawing->ruler, &rect);
1075 /* notify mouse on ruler */
1077 histo_motion_notify_ruler(GtkWidget
*widget
, GdkEventMotion
*event
, gpointer user_data
)
1079 //g_debug("motion");
1080 //eventually follow mouse and show time here
1085 histo_motion_notify_vertical_ruler(GtkWidget
*widget
, GdkEventMotion
*event
, gpointer user_data
)
1087 //g_debug("motion");
1088 //eventually follow mouse and show time here
1094 /* Redraw the vertical ruler */
1096 histo_expose_vertical_ruler( GtkWidget
*widget
, GdkEventExpose
*event
, gpointer user_data
)
1098 histoDrawing_t
*drawing
= (histoDrawing_t
*)user_data
;
1099 HistoControlFlowData
*histo_cfv
= drawing
->histo_control_flow_data
;
1102 PangoContext
*context
;
1103 PangoLayout
*layout
;
1104 PangoFontDescription
*FontDesc
;
1105 PangoRectangle ink_rect
;
1106 gint global_height
=0;
1107 GdkColor foreground
= { 0, 0, 0, 0 };
1108 GdkColor background
= { 0, 0xffff, 0xffff, 0xffff };
1109 GdkColor red
={ 0, 0xFFFF, 0x1E00, 0x1000 };
1110 GdkColor magneta
={ 0, 0x8900, 0x0000, 0x8400 };
1111 g_debug("vertical ruler expose event");
1113 gdk_draw_rectangle (drawing
->vertical_ruler
->window
,
1114 drawing
->vertical_ruler
->style
->white_gc
,
1116 event
->area
.x
, event
->area
.y
,
1118 event
->area
.height
);
1120 gdk_draw_line (drawing
->vertical_ruler
->window
,
1121 drawing
->ruler_gc_butt
,
1122 padding_width
-1/*event->area.width-1*/,event
->area
.y
,
1123 padding_width
-1/*event->area.width-1*/,event
->area
.y
+ event
->area
.height
);
1125 snprintf(text
, 255, "%.1f", (float)histo_cfv
->max_height
);
1127 layout
= gtk_widget_create_pango_layout(drawing
->drawing_area
, NULL
);
1129 context
= pango_layout_get_context(layout
);
1130 FontDesc
= pango_context_get_font_description(context
);
1132 pango_font_description_set_size(FontDesc
, 6*PANGO_SCALE
);
1133 pango_layout_context_changed(layout
);
1135 pango_layout_set_text(layout
, text
, -1);
1136 pango_layout_get_pixel_extents(layout
, &ink_rect
, NULL
);
1137 global_height
+= ink_rect
.height
;
1139 gdk_draw_layout_with_colors(drawing
->vertical_ruler
->window
,
1140 drawing
->ruler_gc_butt
,
1143 layout
, &foreground
, &background
);
1145 gdk_draw_line (drawing
->vertical_ruler
->window
,
1146 drawing
->ruler_gc_round
,
1147 drawing
->vertical_ruler
-> allocation
.width
-1, 1,
1148 drawing
->vertical_ruler
-> allocation
.width
-7, 1);
1151 snprintf(text
, 255, "%d", 0);
1153 pango_layout_set_text(layout
, text
, -1);
1154 pango_layout_get_pixel_extents(layout
, &ink_rect
, NULL
);
1155 global_height
+= ink_rect
.height
;
1157 if(global_height
<= drawing
->vertical_ruler
->allocation
.height
)
1159 gdk_draw_layout_with_colors(drawing
->vertical_ruler
->window
,
1160 drawing
->ruler_gc_butt
,
1162 drawing
->vertical_ruler
->allocation
.height
- ink_rect
.height
-2,
1163 layout
, &foreground
, &background
);
1165 gdk_draw_line (drawing
->vertical_ruler
->window
,
1166 drawing
->ruler_gc_butt
,
1167 drawing
->vertical_ruler
-> allocation
.width
-1,
1168 drawing
->vertical_ruler
->allocation
.height
-1,
1169 drawing
->vertical_ruler
-> allocation
.width
-7,
1170 drawing
->vertical_ruler
->allocation
.height
-1);
1174 snprintf(text
, 255, "%.1f",(float) histo_cfv
->max_height
/2.0);
1176 pango_layout_set_text(layout
, text
, -1);
1177 pango_layout_get_pixel_extents(layout
, &ink_rect
, NULL
);
1178 global_height
+= ink_rect
.height
;
1180 if(global_height
<= drawing
->vertical_ruler
->allocation
.height
)
1182 gdk_draw_layout_with_colors(drawing
->vertical_ruler
->window
,
1183 drawing
->ruler_gc_butt
,
1185 (drawing
->vertical_ruler
->allocation
.height
- ink_rect
.height
)/2,
1186 layout
, &foreground
, &background
);
1188 gdk_draw_line (drawing
->vertical_ruler
->window
,
1189 drawing
->ruler_gc_butt
,
1190 drawing
->vertical_ruler
-> allocation
.width
-1,
1191 drawing
->vertical_ruler
-> allocation
.height
/2,
1192 drawing
->vertical_ruler
-> allocation
.width
-7,
1193 drawing
->vertical_ruler
->allocation
.height
/2);
1196 //show number of events at current time:
1197 LttTime current_time
=
1198 lttvwindow_get_current_time(histo_cfv
->tab
);
1199 TimeWindow time_window
=
1200 lttvwindow_get_time_window(histo_cfv
->tab
);
1201 LttTime time_begin
= time_window
.start_time
;
1202 LttTime time_width
= time_window
.time_width
;
1203 LttTime time_end
= ltt_time_add(time_begin
, time_width
);
1204 if((ltt_time_compare(current_time
, time_begin
) >= 0)&&
1205 (ltt_time_compare(current_time
, time_end
) <= 0))
1207 guint
*events_at_currenttime
;
1208 guint max_height
=histo_cfv
->max_height
;
1210 histo_convert_time_to_pixels(
1215 // if(x_test<histo_cfv->number_of_process->len)
1218 events_at_currenttime
=
1219 &g_array_index(histo_cfv
->number_of_process
,guint
,x
);
1222 if((*events_at_currenttime
) > max_height
)
1224 snprintf(text
, 255, "OverFlow!");
1225 pango_layout_set_text(layout
, text
, -1);
1226 pango_layout_get_pixel_extents(layout
, &ink_rect
, NULL
);
1227 global_height
+= ink_rect
.height
;
1228 gdk_draw_layout_with_colors(drawing
->vertical_ruler
->window
,
1229 drawing
->ruler_gc_butt
,
1231 (drawing
->vertical_ruler
->allocation
.height
- ink_rect
.height
)/5,
1232 layout
, &red
, &background
);
1234 // if((*events_at_currenttime) <= max_height)
1236 snprintf(text
, 255, "%.1f",
1237 (float) *events_at_currenttime
);
1239 pango_layout_set_text(layout
, text
, -1);
1240 pango_layout_get_pixel_extents(layout
, &ink_rect
, NULL
);
1241 global_height
+= ink_rect
.height
;
1243 if ((*events_at_currenttime
) == 0)
1245 gdk_draw_layout_with_colors(drawing
->vertical_ruler
->window
,
1246 drawing
->ruler_gc_butt
,
1248 (drawing
->vertical_ruler
->allocation
.height
- ink_rect
.height
)-2,
1249 layout
, &red
, &background
);
1251 else if ((*events_at_currenttime
) == max_height
)
1253 gdk_draw_layout_with_colors(drawing
->vertical_ruler
->window
,
1254 drawing
->ruler_gc_butt
,
1257 layout
, &red
, &background
);
1259 /*else if ((*events_at_currenttime) == max_height/2)
1261 gdk_draw_layout_with_colors(drawing->vertical_ruler->window,
1262 drawing->ruler_gc_butt,
1264 (drawing->vertical_ruler->allocation.height - ink_rect.height)/2,
1265 layout, &red, &background);
1267 else if ((*events_at_currenttime
) > max_height
/2)
1269 gdk_draw_layout_with_colors(drawing
->vertical_ruler
->window
,
1270 drawing
->ruler_gc_butt
,
1272 (drawing
->vertical_ruler
->allocation
.height
- ink_rect
.height
)/4,
1273 layout
, &red
, &background
);
1276 gdk_draw_layout_with_colors(drawing
->vertical_ruler
->window
,
1277 drawing
->ruler_gc_butt
,
1279 ((drawing
->vertical_ruler
->allocation
.height
1280 - ink_rect
.height
)*3)/4,
1281 layout
, &red
, &background
);
1288 g_object_unref(layout
);