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"
39 #define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
40 #define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
43 #define TRACE_NUMBER 0
44 #define EXTRA_ALLOC 1024 // pixels
45 #define padding_width 50
47 #if 0 /* colors for two lines representation */
48 GdkColor histo_drawing_colors
[NUM_COLORS
] =
49 { /* Pixel, R, G, B */
50 { 0, 0, 0, 0 }, /* COL_BLACK */
51 { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_WHITE */
52 { 0, 0x0FFF, 0xFFFF, 0xFFFF }, /* COL_WAIT_FORK : pale blue */
53 { 0, 0xFFFF, 0xFFFF, 0x0000 }, /* COL_WAIT_CPU : yellow */
54 { 0, 0xFFFF, 0xA000, 0xFCFF }, /* COL_EXIT : pale magenta */
55 { 0, 0xFFFF, 0x0000, 0xFFFF }, /* COL_ZOMBIE : purple */
56 { 0, 0xFFFF, 0x0000, 0x0000 }, /* COL_WAIT : red */
57 { 0, 0x0000, 0xFFFF, 0x0000 }, /* COL_RUN : green */
58 { 0, 0x8800, 0xFFFF, 0x8A00 }, /* COL_USER_MODE : pale green */
59 { 0, 0x09FF, 0x01FF, 0xFFFF }, /* COL_SYSCALL : blue */
60 { 0, 0xF900, 0x4200, 0xFF00 }, /* COL_TRAP : pale purple */
61 { 0, 0xFFFF, 0x5AFF, 0x01FF }, /* COL_IRQ : orange */
62 { 0, 0xFFFF, 0xFFFF, 0xFFFF } /* COL_MODE_UNKNOWN : white */
68 GdkColor histo_drawing_colors
[NUM_COLORS
] =
69 { /* Pixel, R, G, B */
70 { 0, 0, 0, 0 }, /* COL_BLACK */
71 { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_WHITE */
72 { 0, 0x0000, 0xFF00, 0x0000 }, /* COL_RUN_USER_MODE : green */
73 { 0, 0x0100, 0x9E00, 0xFFFF }, /* COL_RUN_SYSCALL : pale blue */
74 { 0, 0xFF00, 0xFF00, 0x0100 }, /* COL_RUN_TRAP : yellow */
75 { 0, 0xFFFF, 0x5E00, 0x0000 }, /* COL_RUN_IRQ : red */
76 { 0, 0x6600, 0x0000, 0x0000 }, /* COL_WAIT : dark red */
77 { 0, 0x7700, 0x7700, 0x0000 }, /* COL_WAIT_CPU : dark yellow */
78 { 0, 0x6400, 0x0000, 0x5D00 }, /* COL_ZOMBIE : dark purple */
79 { 0, 0x0700, 0x6400, 0x0000 }, /* COL_WAIT_FORK : dark green */
80 { 0, 0x8900, 0x0000, 0x8400 }, /* COL_EXIT : "less dark" magenta */
81 { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_MODE_UNKNOWN : white */
82 { 0, 0xFFFF, 0xFFFF, 0xFFFF } /* COL_UNNAMED : white */
92 WAIT CPU + WAIT FORK vert foncé ou jaune
101 /*****************************************************************************
102 * drawing functions *
103 *****************************************************************************/
106 histo_expose_ruler( GtkWidget
*widget
, GdkEventExpose
*event
, gpointer user_data
);
109 histo_expose_vertical_ruler( GtkWidget
*widget
, GdkEventExpose
*event
, gpointer user_data
);
112 histo_motion_notify_ruler(GtkWidget
*widget
, GdkEventMotion
*event
, gpointer user_data
);
115 histo_motion_notify_vertical_ruler(GtkWidget
*widget
, GdkEventMotion
*event
, gpointer user_data
);
117 /* Function responsible for updating the exposed area.
118 * It must do an events request to the lttvwindow API to ask for this update.
119 * Note : this function cannot clear the background, because it may
120 * erase drawing already present (SAFETY).
122 void histo_drawing_data_request(histoDrawing_t
*drawing
,
131 void histo_drawing_data_request_begin(EventsRequest
*events_request
, LttvTracesetState
*tss
)
133 g_debug("Begin of data request");
134 HistoControlFlowData
*cfd
= events_request
->viewer_data
;
135 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tss
);
136 TimeWindow time_window
=
137 lttvwindow_get_time_window(cfd
->tab
);
139 guint width
= cfd
->drawing
->width
;
142 cfd
->drawing
->last_start
= events_request
->start_time
;
144 histo_convert_time_to_pixels(
146 events_request
->start_time
,
152 void histo_drawing_chunk_begin(EventsRequest
*events_request
, LttvTracesetState
*tss
)
154 g_debug("Begin of chunk");
155 HistoControlFlowData
*cfd
= events_request
->viewer_data
;
156 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tss
);
157 //LttTime current_time = lttv_traceset_context_get_current_tfc(tsc)->timestamp;
159 ltt_trace_get_num_cpu(tss
->parent
.traces
[TRACE_NUMBER
]->t
);
161 /* //disabled for histogram
162 cfd->process_list->current_hash_data = g_new(HashedProcessData*,num_cpu);
163 memset(cfd->process_list->current_hash_data, 0,
164 sizeof(HashedProcessData*)*num_cpu);*/
165 //cfd->drawing->last_start = LTT_TIME_MIN(current_time,
166 // events_request->end_time);
170 void histo_drawing_request_expose(EventsRequest
*events_request
,
171 LttvTracesetState
*tss
,
174 HistoControlFlowData
*cfd
= events_request
->viewer_data
;
175 histoDrawing_t
*drawing
= cfd
->drawing
;
177 gint x
, x_end
, width
;
178 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)tss
;
180 TimeWindow time_window
=
181 lttvwindow_get_time_window(cfd
->tab
);
183 g_debug("histo request expose");
185 histo_convert_time_to_pixels(
190 x
= drawing
->damage_begin
;
194 drawing
->damage_begin
= x
+width
;
197 //changed for histogram:
198 gtk_widget_queue_draw_area ( drawing
->drawing_area
,
201 drawing
->/*drawing_area->allocation.*/height
);
203 // Update directly when scrolling
204 gdk_window_process_updates(drawing
->drawing_area
->window
,
212 /* Create a new backing pixmap of the appropriate size */
213 /* As the scaling will always change, it's of no use to copy old
216 * Change the size if width or height changes.
217 * (different from control flow viewer!)
220 histo_configure_event( GtkWidget
*widget
, GdkEventConfigure
*event
,
223 histoDrawing_t
*drawing
= (histoDrawing_t
*)user_data
;
225 /* First, get the new time interval of the main window */
226 /* we assume (see documentation) that the main window
227 * has updated the time interval before this configure gets
230 //lttvwindow_get_time_window(drawing->histo_control_flow_data->mw,
231 // &drawing->histo_control_flow_data->time_window);
233 /* New pixmap, size of the configure event */
234 //GdkPixmap *pixmap = gdk_pixmap_new(widget->window,
235 // widget->allocation.width + SAFETY,
236 // widget->allocation.height + SAFETY,
238 g_debug("drawing configure event");
239 g_debug("New alloc draw size : %i by %i",widget
->allocation
.width
,
240 widget
->allocation
.height
);
242 /*modified for histogram, if width is not changed, GArray is valid so
243 just redraw, else recalculate all.(event request again)*/
245 //enabled again for histogram:
247 gdk_pixmap_unref(drawing
->pixmap
);
249 drawing
->pixmap
= gdk_pixmap_new(widget
->window
,
250 widget
->allocation
.width
,//+ SAFETY + EXTRA_ALLOC,
251 widget
->allocation
.height
+ EXTRA_ALLOC
,
255 drawing
->alloc_width
= drawing
->width
+ SAFETY
+ EXTRA_ALLOC
;
256 drawing
->alloc_height
= drawing
->height
+ EXTRA_ALLOC
;
258 //drawing->height = widget->allocation.height;
263 // gdk_draw_rectangle (drawing->pixmap,
264 // widget->style->black_gc,
267 // drawing->width+SAFETY,
270 //g_info("init data request");
273 /* Initial data request */
274 /* no, do initial data request in the expose event */
275 // Do not need to ask for data of 1 pixel : not synchronized with
276 // main window time at this moment.
277 //histo_drawing_data_request(drawing, &drawing->pixmap, 0, 0,
278 // widget->allocation.width,
279 // widget->allocation.height);
281 //drawing->width = widget->allocation.width;
282 //drawing->height = widget->allocation.height;
284 drawing
->damage_begin
= 0;
285 drawing
->damage_end
= widget
->allocation
.width
;
287 if((widget
->allocation
.width
!= 1 &&
288 widget
->allocation
.height
!= 1)
289 /*&& drawing->damage_begin < drawing->damage_end */)
292 gdk_draw_rectangle (drawing
->pixmap
,
293 drawing
->drawing_area
->style
->black_gc
,
296 drawing
->drawing_area
->allocation
.width
, drawing
->drawing_area
->allocation
.height
);
297 /* histo_drawing_data_request(drawing,
298 drawing->damage_begin,
300 drawing->damage_end - drawing->damage_begin,
303 //modified for histogram
305 if(widget
->allocation
.width
== drawing
->width
)
308 drawing
->height
= widget
->allocation
.height
;
309 histogram_show( drawing
->histo_control_flow_data
,0,
310 drawing
->histo_control_flow_data
->number_of_process
->len
);
314 drawing
->width
= widget
->allocation
.width
;
315 drawing
->height
= widget
->allocation
.height
;
317 g_array_set_size (drawing
->histo_control_flow_data
->number_of_process
,
318 widget
->allocation
.width
);
319 histo_request_event( drawing
->histo_control_flow_data
,drawing
->damage_begin
320 ,drawing
->damage_end
- drawing
->damage_begin
);
326 /* Redraw the screen from the backing pixmap */
328 histo_expose_event( GtkWidget
*widget
, GdkEventExpose
*event
, gpointer user_data
)
330 histoDrawing_t
*drawing
= (histoDrawing_t
*)user_data
;
332 HistoControlFlowData
*histo_control_flow_data
=
333 (HistoControlFlowData
*)g_object_get_data(
335 "histo_control_flow_data");
337 if(unlikely(drawing
->gc
== NULL
)) {
338 drawing
->gc
= gdk_gc_new(drawing
->drawing_area
->window
);
339 gdk_gc_copy(drawing
->gc
, drawing
->drawing_area
->style
->black_gc
);
342 TimeWindow time_window
=
343 lttvwindow_get_time_window(histo_control_flow_data
->tab
);
344 LttTime current_time
=
345 lttvwindow_get_current_time(histo_control_flow_data
->tab
);
349 LttTime window_end
= time_window
.end_time
;
352 /* update the screen from the pixmap buffer */
353 //added again for histogram:
355 gdk_draw_pixmap(widget
->window
,
356 widget
->style
->fg_gc
[GTK_WIDGET_STATE (widget
)],
358 event
->area
.x
, event
->area
.y
,
359 event
->area
.x
, event
->area
.y
,
360 event
->area
.width
, event
->area
.height
);
363 drawing
->height
= drawing
-> drawing_area
->allocation
.height
;
366 copy_pixmap_to_screen(histo_control_flow_data
->process_list
,
368 widget
->style
->fg_gc
[GTK_WIDGET_STATE (widget
)],
369 event
->area
.x
, event
->area
.y
,
370 event
->area
.width
, event
->area
.height
);
374 /* //disabled for histogram
375 copy_pixmap_to_screen(histo_control_flow_data->process_list,
378 event->area.x, event->area.y,
379 event->area.width, event->area.height);*/
381 /* Erase the dotted lines left.. */
382 if(widget
->allocation
.height
> drawing
->height
)
384 gdk_draw_rectangle (widget
->window
,
385 drawing
->drawing_area
->style
->black_gc
,
387 event
->area
.x
, drawing
->height
,
388 event
->area
.width
, // do not overlap
389 widget
->allocation
.height
- drawing
->height
);
391 if(ltt_time_compare(time_window
.start_time
, current_time
) <= 0 &&
392 ltt_time_compare(window_end
, current_time
) >= 0)
394 /* Draw the dotted lines */
395 histo_convert_time_to_pixels(
402 if(drawing
->dotted_gc
== NULL
) {
404 drawing
->dotted_gc
= gdk_gc_new(drawing
->drawing_area
->window
);
405 gdk_gc_copy(drawing
->dotted_gc
, widget
->style
->white_gc
);
407 gint8 dash_list
[] = { 1, 2 };
408 gdk_gc_set_line_attributes(drawing
->dotted_gc
,
410 GDK_LINE_ON_OFF_DASH
,
413 gdk_gc_set_dashes(drawing
->dotted_gc
,
419 gint height_tot
= MAX(widget
->allocation
.height
, drawing
->height
);
420 gdk_draw_line(widget
->window
,
423 cursor_x
, height_tot
);
430 histo_after_expose_event( GtkWidget
*widget
, GdkEventExpose
*event
, gpointer user_data
)
433 g_debug("AFTER EXPOSE");
440 histo_button_press_event( GtkWidget
*widget
, GdkEventButton
*event
, gpointer user_data
)
442 HistoControlFlowData
*histo_control_flow_data
=
443 (HistoControlFlowData
*)g_object_get_data(
445 "histo_control_flow_data");
446 histoDrawing_t
*drawing
= histo_control_flow_data
->drawing
;
447 TimeWindow time_window
=
448 lttvwindow_get_time_window(histo_control_flow_data
->tab
);
451 if(event
->button
== 1)
455 /* left mouse button click */
456 g_debug("x click is : %f", event
->x
);
458 histo_convert_pixels_to_time(drawing
->width
, (guint
)event
->x
,
462 lttvwindow_report_current_time(histo_control_flow_data
->tab
, time
);
463 ////report event->y for vertical zoom +,-
469 //Viewer's vertical scroll bar is already omitted, not needed for histogram.
471 scrollbar_size_allocate(GtkWidget *widget,
472 GtkAllocation *allocation,
475 histoDrawing_t *drawing = (histoDrawing_t*)user_data;
477 gtk_widget_set_size_request(drawing->padding, allocation->width, -1);
478 //gtk_widget_queue_resize(drawing->padding);
479 //gtk_widget_queue_resize(drawing->ruler);
480 gtk_container_check_resize(GTK_CONTAINER(drawing->ruler_hbox));
486 histoDrawing_t
*histo_drawing_construct(HistoControlFlowData
*histo_control_flow_data
)
488 histoDrawing_t
*drawing
= g_new(histoDrawing_t
, 1);
490 drawing
->histo_control_flow_data
= histo_control_flow_data
;
492 drawing
->vbox
= gtk_vbox_new(FALSE
, 1);
495 drawing
->ruler_hbox
= gtk_hbox_new(FALSE
, 1);
496 drawing
->ruler
= gtk_drawing_area_new ();
497 //gtk_widget_set_size_request(drawing->ruler, -1, 27);
499 drawing
->padding
= gtk_drawing_area_new ();
500 //gtk_widget_set_size_request(drawing->padding, -1, 27);
502 gtk_box_pack_start(GTK_BOX(drawing
->ruler_hbox
), drawing
->padding
,FALSE
, FALSE
, 0);
504 gtk_box_pack_end(GTK_BOX(drawing
->ruler_hbox
), drawing
->ruler
,
507 drawing
->drawing_area
= gtk_drawing_area_new ();
511 ///at this time not necessary for histogram
512 drawing->hbox = gtk_hbox_new(FALSE, 1);
514 drawing->viewport = gtk_viewport_new(NULL, histo_control_flow_data->v_adjust);
515 drawing->scrollbar = gtk_vscrollbar_new(histo_control_flow_data->v_adjust);
516 gtk_box_pack_start(GTK_BOX(drawing->hbox), drawing->viewport,
518 gtk_box_pack_end(GTK_BOX(drawing->hbox), drawing->scrollbar,
520 gtk_container_add(GTK_CONTAINER(drawing->viewport),
521 drawing->drawing_area);*/
523 //add vertical ruler:
524 drawing
->vruler_drawing_hbox
= gtk_hbox_new(FALSE
, 1);
525 drawing
-> vertical_ruler
=gtk_drawing_area_new ();
526 gtk_box_pack_start(GTK_BOX(drawing
->vruler_drawing_hbox
), drawing
->vertical_ruler
,
528 gtk_box_pack_end(GTK_BOX(drawing
->vruler_drawing_hbox
), drawing
->drawing_area
,
530 gtk_widget_set_size_request(drawing
->vertical_ruler
, padding_width
, -1);
532 gtk_box_pack_start(GTK_BOX(drawing
->vbox
), drawing
->ruler_hbox
,
534 gtk_box_pack_end(GTK_BOX(drawing
->vbox
), drawing
->vruler_drawing_hbox
/*drawing_area*/,
537 drawing
->pango_layout
=
538 gtk_widget_create_pango_layout(drawing
->drawing_area
, NULL
);
543 drawing
->alloc_height
= 1;
544 drawing
->alloc_width
= 1;
546 drawing
->damage_begin
= 0;
547 drawing
->damage_end
= 0;
548 drawing
->horizontal_sel
= -1;
550 //gtk_widget_set_size_request(drawing->drawing_area->window, 50, 50);
551 g_object_set_data_full(
552 G_OBJECT(drawing
->drawing_area
),
553 "histo_Link_drawing_Data",
555 (GDestroyNotify
)histo_drawing_destroy
);
558 G_OBJECT(drawing
->ruler
),
563 G_OBJECT(drawing
->vertical_ruler
),
567 //gtk_widget_modify_bg( drawing->drawing_area,
569 // &CF_Colors[BLACK]);
571 //gdk_window_get_geometry(drawing->drawing_area->window,
573 // &(drawing->width),
574 // &(drawing->height),
577 //drawing->pixmap = gdk_pixmap_new(
578 // drawing->drawing_area->window,
583 drawing
->pixmap
= NULL
;
585 // drawing->pixmap = gdk_pixmap_new(drawing->drawing_area->window,
586 // drawing->drawing_area->allocation.width,
587 // drawing->drawing_area->allocation.height,
590 g_signal_connect (G_OBJECT(drawing
->drawing_area
),
592 G_CALLBACK (histo_configure_event
),
595 g_signal_connect (G_OBJECT(drawing
->ruler
),
597 G_CALLBACK(histo_expose_ruler
),
600 gtk_widget_add_events(drawing
->ruler
, GDK_POINTER_MOTION_MASK
);
601 gtk_widget_add_events(drawing
->vertical_ruler
, GDK_POINTER_MOTION_MASK
);
603 g_signal_connect (G_OBJECT(drawing
->ruler
),
604 "motion-notify-event",
605 G_CALLBACK(histo_motion_notify_ruler
),
609 g_signal_connect (G_OBJECT(drawing
->vertical_ruler
),
611 G_CALLBACK(histo_expose_vertical_ruler
),
614 g_signal_connect (G_OBJECT(drawing
->vertical_ruler
),
615 "motion-notify-event",
616 G_CALLBACK(histo_motion_notify_vertical_ruler
),
619 /*//not necessary for historam.
620 g_signal_connect (G_OBJECT(drawing->drawing_area),
622 G_CALLBACK(scrollbar_size_allocate),
623 (gpointer)drawing); */
626 gtk_widget_set_size_request(drawing
->padding
, padding_width
, -1);//use it for vertical ruler
628 g_signal_connect (G_OBJECT(drawing
->drawing_area
),
630 G_CALLBACK (histo_expose_event
),
633 g_signal_connect_after (G_OBJECT(drawing
->drawing_area
),
635 G_CALLBACK (histo_after_expose_event
),
638 g_signal_connect (G_OBJECT(drawing
->drawing_area
),
639 "button-press-event",
640 G_CALLBACK (histo_button_press_event
),
643 gtk_widget_show(drawing
->ruler
);
644 gtk_widget_show(drawing
->padding
);
645 gtk_widget_show(drawing
->ruler_hbox
);
646 gtk_widget_show(drawing
->vertical_ruler
);
647 gtk_widget_show(drawing
->vruler_drawing_hbox
);
648 gtk_widget_show(drawing
->drawing_area
);
650 /// gtk_widget_show(drawing->viewport);
651 /// gtk_widget_show(drawing->scrollbar);
652 /// gtk_widget_show(drawing->hbox);
654 /* Allocate the colors */
655 GdkColormap
* colormap
= gdk_colormap_get_system();
656 gboolean success
[NUM_COLORS
];
657 gdk_colormap_alloc_colors(colormap
, histo_drawing_colors
, NUM_COLORS
, FALSE
,
661 gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(histo_control_flow_data
->tab
)->window
));
663 gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(histo_control_flow_data
->tab
)->window
));
665 gdk_gc_copy(drawing
->gc
,
666 main_window_get_widget(histo_control_flow_data
->tab
)->style
->black_gc
);
667 gdk_gc_copy(drawing
->dotted_gc
,
668 main_window_get_widget(histo_control_flow_data
->tab
)->style
->white_gc
);
670 gint8 dash_list
[] = { 1, 2 };
671 gdk_gc_set_line_attributes(drawing
->dotted_gc
,
673 GDK_LINE_ON_OFF_DASH
,
676 gdk_gc_set_dashes(drawing
->dotted_gc
,
681 drawing
->ruler_gc_butt
=
682 gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(histo_control_flow_data
->tab
)->window
));
683 gdk_gc_copy(drawing
->ruler_gc_butt
,
684 main_window_get_widget(histo_control_flow_data
->tab
)->style
->black_gc
);
685 drawing
->ruler_gc_round
=
686 gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(histo_control_flow_data
->tab
)->window
));
687 gdk_gc_copy(drawing
->ruler_gc_round
,
688 main_window_get_widget(histo_control_flow_data
->tab
)->style
->black_gc
);
691 gdk_gc_set_line_attributes(drawing
->ruler_gc_butt
,
697 gdk_gc_set_line_attributes(drawing
->ruler_gc_round
,
705 void histo_drawing_destroy(histoDrawing_t
*drawing
)
707 g_info("histo_drawing_destroy %p", drawing
);
709 /* Free the colors */
710 GdkColormap
* colormap
= gdk_colormap_get_system();
712 gdk_colormap_free_colors(colormap
, histo_drawing_colors
, NUM_COLORS
);
714 // Do not unref here, histoDrawing_t destroyed by it's widget.
715 //g_object_unref( G_OBJECT(drawing->drawing_area));
716 if(drawing
->gc
!= NULL
)
717 gdk_gc_unref(drawing
->gc
);
719 g_object_unref(drawing
->pango_layout
);
720 if(drawing
->dotted_gc
!= NULL
) gdk_gc_unref(drawing
->dotted_gc
);
721 if(drawing
->ruler_gc_butt
!= NULL
) gdk_gc_unref(drawing
->ruler_gc_butt
);
722 if(drawing
->ruler_gc_round
!= NULL
) gdk_gc_unref(drawing
->ruler_gc_round
);
724 //added for histogram
726 gdk_pixmap_unref(drawing
->pixmap
);
728 g_info("histo_drawing_destroy end");
731 GtkWidget
*histo_drawing_get_drawing_area(histoDrawing_t
*drawing
)
733 return drawing
->drawing_area
;
736 GtkWidget
*histo_drawing_get_widget(histoDrawing_t
*drawing
)
738 return drawing
->vbox
;
741 void histo_drawing_draw_line( histoDrawing_t
*drawing
,
747 gdk_draw_line (pixmap
,
752 void histo_drawing_clear(histoDrawing_t
*drawing
,guint clear_from
,guint clear_to
)
755 HistoControlFlowData
*cfd
= drawing
->histo_control_flow_data
;
756 guint clear_width
= clear_to
- clear_from
;
758 //disabled for histogram
759 rectangle_pixmap(cfd->process_list,
760 drawing->drawing_area->style->black_gc,
763 drawing->alloc_width, // do not overlap
765 //instead, this is added for histogram
767 histo_rectangle_pixmap (drawing
->drawing_area
->style
->black_gc
,
770 clear_width
/*drawing->width*/,
775 /* gdk_draw_rectangle (drawing->pixmap,
776 drawing->drawing_area->style->black_gc,
779 drawing->drawing_area->allocation.width,drawing->drawing_area->allocation.height );
781 /* ask for the buffer to be redrawn */
782 //enabled again for histogram.
783 gtk_widget_queue_draw_area ( drawing
->drawing_area
,
785 clear_width
, drawing
->height
);
786 gdk_window_process_updates(drawing
->drawing_area
->window
,TRUE
);
787 //disabled instead for histogram
788 //gtk_widget_queue_draw ( drawing->drawing_area);
793 /* Insert a square corresponding to a new process in the list */
794 /* Applies to whole drawing->width */
795 void drawing_insert_square(histoDrawing_t
*drawing
,
799 //GdkRectangle update_rect;
800 gboolean reallocate
= FALSE
;
801 GdkPixmap
*new_pixmap
;
803 /* Allocate a new pixmap with new height */
804 if(drawing
->alloc_height
< drawing
->height
+ height
) {
806 new_pixmap
= gdk_pixmap_new(drawing
->drawing_area
->window
,
807 drawing
->width
+ SAFETY
+ EXTRA_ALLOC
,
808 drawing
->height
+ height
+ EXTRA_ALLOC
,
810 drawing
->alloc_width
= drawing
->width
+ SAFETY
+ EXTRA_ALLOC
;
811 drawing
->alloc_height
= drawing
->height
+ height
+ EXTRA_ALLOC
;
814 /* Copy the high region */
815 gdk_draw_pixmap (new_pixmap
,
816 drawing
->drawing_area
->style
->black_gc
,
820 drawing
->width
+ SAFETY
, y
);
823 new_pixmap
= drawing
->pixmap
;
826 //GdkPixmap *pixmap = gdk_pixmap_new(drawing->drawing_area->window,
827 // drawing->width + SAFETY,
828 // drawing->height + height,
831 /* add an empty square */
832 gdk_draw_rectangle (new_pixmap
,
833 drawing
->drawing_area
->style
->black_gc
,
836 drawing
->width
+ SAFETY
, // do not overlap
839 /* copy the bottom of the region */
840 gdk_draw_pixmap (new_pixmap
,
841 drawing
->drawing_area
->style
->black_gc
,
845 drawing
->width
+SAFETY
, drawing
->height
- y
);
848 if(reallocate
&& likely(drawing
->pixmap
)) {
849 gdk_pixmap_unref(drawing
->pixmap
);
850 drawing
->pixmap
= new_pixmap
;
853 if(unlikely(drawing
->height
==1)) drawing
->height
= height
;
854 else drawing
->height
+= height
;
856 gtk_widget_set_size_request(drawing
->drawing_area
,
859 gtk_widget_queue_resize_no_redraw(drawing
->drawing_area
);
861 /* ask for the buffer to be redrawn */
862 gtk_widget_queue_draw_area ( drawing
->drawing_area
,
864 drawing
->width
, drawing
->height
-y
);
868 /* Remove a square corresponding to a removed process in the list */
869 void drawing_remove_square(histoDrawing_t
*drawing
,
875 if(unlikely((guint
)drawing
->height
== height
)) {
876 //pixmap = gdk_pixmap_new(
877 // drawing->drawing_area->window,
878 // drawing->width + SAFETY,
881 pixmap
= drawing
->pixmap
;
884 /* Allocate a new pixmap with new height */
885 //pixmap = gdk_pixmap_new(
886 // drawing->drawing_area->window,
887 // drawing->width + SAFETY,
888 // drawing->height - height,
890 /* Keep the same preallocated pixmap */
891 pixmap
= drawing
->pixmap
;
893 /* Copy the high region */
894 gdk_draw_pixmap (pixmap
,
895 drawing
->drawing_area
->style
->black_gc
,
899 drawing
->width
+ SAFETY
, y
);
901 /* Copy up the bottom of the region */
902 gdk_draw_pixmap (pixmap
,
903 drawing
->drawing_area
->style
->black_gc
,
907 drawing
->width
, drawing
->height
- y
- height
);
909 drawing
->height
-=height
;
912 //if(likely(drawing->pixmap))
913 // gdk_pixmap_unref(drawing->pixmap);
915 //drawing->pixmap = pixmap;
917 gtk_widget_set_size_request(drawing
->drawing_area
,
920 gtk_widget_queue_resize_no_redraw(drawing
->drawing_area
);
921 /* ask for the buffer to be redrawn */
922 gtk_widget_queue_draw_area ( drawing
->drawing_area
,
924 drawing
->width
, MAX(drawing
->height
-y
, 1));
928 void histo_drawing_update_ruler(histoDrawing_t
*drawing
, TimeWindow
*time_window
)
933 req
.width
= drawing
->ruler
->allocation
.width
;
934 req
.height
= drawing
->ruler
->allocation
.height
;
939 rect
.width
= req
.width
;
940 rect
.height
= req
.height
;
942 gtk_widget_queue_draw(drawing
->ruler
);
943 //gtk_widget_draw( drawing->ruler, &rect);
946 /* Redraw the ruler */
948 histo_expose_ruler( GtkWidget
*widget
, GdkEventExpose
*event
, gpointer user_data
)
950 histoDrawing_t
*drawing
= (histoDrawing_t
*)user_data
;
951 TimeWindow time_window
= lttvwindow_get_time_window(drawing
->histo_control_flow_data
->tab
);
954 PangoContext
*context
;
956 PangoFontDescription
*FontDesc
;
957 PangoRectangle ink_rect
;
959 GdkColor foreground
= { 0, 0, 0, 0 };
960 GdkColor background
= { 0, 0xffff, 0xffff, 0xffff };
962 LttTime window_end
= time_window
.end_time
;
964 ltt_time_div(time_window
.time_width
,2.0);
965 LttTime window_middle
=
966 ltt_time_add(half_width
,
967 time_window
.start_time
);
968 g_debug("ruler expose event");
970 gdk_draw_rectangle (drawing
->ruler
->window
,
971 drawing
->ruler
->style
->white_gc
,
973 event
->area
.x
, event
->area
.y
,
977 gdk_draw_line (drawing
->ruler
->window
,
978 drawing
->ruler_gc_butt
,
980 event
->area
.x
+ event
->area
.width
, 1);
983 snprintf(text
, 255, "%lus\n%luns",
984 time_window
.start_time
.tv_sec
,
985 time_window
.start_time
.tv_nsec
);
987 layout
= gtk_widget_create_pango_layout(drawing
->drawing_area
, NULL
);
989 context
= pango_layout_get_context(layout
);
990 FontDesc
= pango_context_get_font_description(context
);
992 pango_font_description_set_size(FontDesc
, 6*PANGO_SCALE
);
993 pango_layout_context_changed(layout
);
995 pango_layout_set_text(layout
, text
, -1);
996 pango_layout_get_pixel_extents(layout
, &ink_rect
, NULL
);
997 global_width
+= ink_rect
.width
;
999 gdk_draw_layout_with_colors(drawing
->ruler
->window
,
1000 drawing
->ruler_gc_butt
,
1003 layout
, &foreground
, &background
);
1005 gdk_draw_line (drawing
->ruler
->window
,
1006 drawing
->ruler_gc_round
,
1011 snprintf(text
, 255, "%lus\n%luns", window_end
.tv_sec
,
1012 window_end
.tv_nsec
);
1014 pango_layout_set_text(layout
, text
, -1);
1015 pango_layout_get_pixel_extents(layout
, &ink_rect
, NULL
);
1016 global_width
+= ink_rect
.width
;
1018 if(global_width
<= drawing
->ruler
->allocation
.width
)
1020 gdk_draw_layout_with_colors(drawing
->ruler
->window
,
1021 drawing
->ruler_gc_butt
,
1022 drawing
->ruler
->allocation
.width
- ink_rect
.width
,
1024 layout
, &foreground
, &background
);
1026 gdk_draw_line (drawing
->ruler
->window
,
1027 drawing
->ruler_gc_butt
,
1028 drawing
->ruler
->allocation
.width
-1, 1,
1029 drawing
->ruler
->allocation
.width
-1, 7);
1033 snprintf(text
, 255, "%lus\n%luns", window_middle
.tv_sec
,
1034 window_middle
.tv_nsec
);
1036 pango_layout_set_text(layout
, text
, -1);
1037 pango_layout_get_pixel_extents(layout
, &ink_rect
, NULL
);
1038 global_width
+= ink_rect
.width
;
1040 if(global_width
<= drawing
->ruler
->allocation
.width
)
1042 gdk_draw_layout_with_colors(drawing
->ruler
->window
,
1043 drawing
->ruler_gc_butt
,
1044 (drawing
->ruler
->allocation
.width
- ink_rect
.width
)/2,
1046 layout
, &foreground
, &background
);
1048 gdk_draw_line (drawing
->ruler
->window
,
1049 drawing
->ruler_gc_butt
,
1050 drawing
->ruler
->allocation
.width
/2, 1,
1051 drawing
->ruler
->allocation
.width
/2, 7);
1054 g_object_unref(layout
);
1059 void histo_drawing_update_vertical_ruler(histoDrawing_t
*drawing
)//, TimeWindow *time_window)
1064 req
.width
= drawing
->vertical_ruler
->allocation
.width
;
1065 req
.height
= drawing
->vertical_ruler
->allocation
.height
;
1069 rect
.width
= req
.width
;
1070 rect
.height
= req
.height
;
1072 gtk_widget_queue_draw(drawing
->vertical_ruler
);
1073 //gtk_widget_draw( drawing->ruler, &rect);
1076 /* notify mouse on ruler */
1078 histo_motion_notify_ruler(GtkWidget
*widget
, GdkEventMotion
*event
, gpointer user_data
)
1080 //g_debug("motion");
1081 //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
1093 /* Redraw the vertical ruler */
1095 histo_expose_vertical_ruler( GtkWidget
*widget
, GdkEventExpose
*event
, gpointer user_data
)
1097 histoDrawing_t
*drawing
= (histoDrawing_t
*)user_data
;
1098 HistoControlFlowData
*histo_cfv
= drawing
->histo_control_flow_data
;
1101 PangoContext
*context
;
1102 PangoLayout
*layout
;
1103 PangoFontDescription
*FontDesc
;
1104 PangoRectangle ink_rect
;
1105 gint global_height
=0;
1106 GdkColor foreground
= { 0, 0, 0, 0 };
1107 GdkColor background
= { 0, 0xffff, 0xffff, 0xffff };
1108 GdkColor red
={ 0, 0xFFFF, 0x1E00, 0x1000 };
1109 GdkColor magneta
={ 0, 0x8900, 0x0000, 0x8400 };
1110 g_debug("vertical ruler expose event");
1112 gdk_draw_rectangle (drawing
->vertical_ruler
->window
,
1113 drawing
->vertical_ruler
->style
->white_gc
,
1115 event
->area
.x
, event
->area
.y
,
1117 event
->area
.height
);
1119 gdk_draw_line (drawing
->vertical_ruler
->window
,
1120 drawing
->ruler_gc_butt
,
1121 padding_width
-1/*event->area.width-1*/,event
->area
.y
,
1122 padding_width
-1/*event->area.width-1*/,event
->area
.y
+ event
->area
.height
);
1124 snprintf(text
, 255, "%.1f", (float)histo_cfv
->max_height
);
1126 layout
= gtk_widget_create_pango_layout(drawing
->drawing_area
, NULL
);
1128 context
= pango_layout_get_context(layout
);
1129 FontDesc
= pango_context_get_font_description(context
);
1131 pango_font_description_set_size(FontDesc
, 6*PANGO_SCALE
);
1132 pango_layout_context_changed(layout
);
1134 pango_layout_set_text(layout
, text
, -1);
1135 pango_layout_get_pixel_extents(layout
, &ink_rect
, NULL
);
1136 global_height
+= ink_rect
.height
;
1138 gdk_draw_layout_with_colors(drawing
->vertical_ruler
->window
,
1139 drawing
->ruler_gc_butt
,
1142 layout
, &foreground
, &background
);
1144 gdk_draw_line (drawing
->vertical_ruler
->window
,
1145 drawing
->ruler_gc_round
,
1146 drawing
->vertical_ruler
-> allocation
.width
-1, 1,
1147 drawing
->vertical_ruler
-> allocation
.width
-7, 1);
1150 snprintf(text
, 255, "%lu",0);
1152 pango_layout_set_text(layout
, text
, -1);
1153 pango_layout_get_pixel_extents(layout
, &ink_rect
, NULL
);
1154 global_height
+= ink_rect
.height
;
1156 if(global_height
<= drawing
->vertical_ruler
->allocation
.height
)
1158 gdk_draw_layout_with_colors(drawing
->vertical_ruler
->window
,
1159 drawing
->ruler_gc_butt
,
1161 drawing
->vertical_ruler
->allocation
.height
- ink_rect
.height
-2,
1162 layout
, &foreground
, &background
);
1164 gdk_draw_line (drawing
->vertical_ruler
->window
,
1165 drawing
->ruler_gc_butt
,
1166 drawing
->vertical_ruler
-> allocation
.width
-1,
1167 drawing
->vertical_ruler
->allocation
.height
-1,
1168 drawing
->vertical_ruler
-> allocation
.width
-7,
1169 drawing
->vertical_ruler
->allocation
.height
-1);
1173 snprintf(text
, 255, "%.1f",(float) histo_cfv
->max_height
/2.0);
1175 pango_layout_set_text(layout
, text
, -1);
1176 pango_layout_get_pixel_extents(layout
, &ink_rect
, NULL
);
1177 global_height
+= ink_rect
.height
;
1179 if(global_height
<= drawing
->vertical_ruler
->allocation
.height
)
1181 gdk_draw_layout_with_colors(drawing
->vertical_ruler
->window
,
1182 drawing
->ruler_gc_butt
,
1184 (drawing
->vertical_ruler
->allocation
.height
- ink_rect
.height
)/2,
1185 layout
, &foreground
, &background
);
1187 gdk_draw_line (drawing
->vertical_ruler
->window
,
1188 drawing
->ruler_gc_butt
,
1189 drawing
->vertical_ruler
-> allocation
.width
-1,
1190 drawing
->vertical_ruler
-> allocation
.height
/2,
1191 drawing
->vertical_ruler
-> allocation
.width
-7,
1192 drawing
->vertical_ruler
->allocation
.height
/2);
1195 //show number of events at current time:
1196 LttTime current_time
=
1197 lttvwindow_get_current_time(histo_cfv
->tab
);
1198 TimeWindow time_window
=
1199 lttvwindow_get_time_window(histo_cfv
->tab
);
1200 LttTime time_begin
= time_window
.start_time
;
1201 LttTime time_width
= time_window
.time_width
;
1202 LttTime time_end
= ltt_time_add(time_begin
, time_width
);
1203 if((ltt_time_compare(current_time
, time_begin
) >= 0)&&
1204 (ltt_time_compare(current_time
, time_end
) <= 0))
1206 guint
*events_at_currenttime
;
1207 guint max_height
=histo_cfv
->max_height
;
1209 histo_convert_time_to_pixels(
1214 // if(x_test<histo_cfv->number_of_process->len)
1217 events_at_currenttime
=
1218 &g_array_index(histo_cfv
->number_of_process
,guint
,x
);
1221 if((*events_at_currenttime
) > max_height
)
1223 snprintf(text
, 255, "OverFlow!");
1224 pango_layout_set_text(layout
, text
, -1);
1225 pango_layout_get_pixel_extents(layout
, &ink_rect
, NULL
);
1226 global_height
+= ink_rect
.height
;
1227 gdk_draw_layout_with_colors(drawing
->vertical_ruler
->window
,
1228 drawing
->ruler_gc_butt
,
1230 (drawing
->vertical_ruler
->allocation
.height
- ink_rect
.height
)/5,
1231 layout
, &red
, &background
);
1233 // if((*events_at_currenttime) <= max_height)
1235 snprintf(text
, 255, "%.1f",
1236 (float) *events_at_currenttime
);
1238 pango_layout_set_text(layout
, text
, -1);
1239 pango_layout_get_pixel_extents(layout
, &ink_rect
, NULL
);
1240 global_height
+= ink_rect
.height
;
1242 if ((*events_at_currenttime
) == 0)
1244 gdk_draw_layout_with_colors(drawing
->vertical_ruler
->window
,
1245 drawing
->ruler_gc_butt
,
1247 (drawing
->vertical_ruler
->allocation
.height
- ink_rect
.height
)-2,
1248 layout
, &red
, &background
);
1250 else if ((*events_at_currenttime
) == max_height
)
1252 gdk_draw_layout_with_colors(drawing
->vertical_ruler
->window
,
1253 drawing
->ruler_gc_butt
,
1256 layout
, &red
, &background
);
1258 /*else if ((*events_at_currenttime) == max_height/2)
1260 gdk_draw_layout_with_colors(drawing->vertical_ruler->window,
1261 drawing->ruler_gc_butt,
1263 (drawing->vertical_ruler->allocation.height - ink_rect.height)/2,
1264 layout, &red, &background);
1266 else if ((*events_at_currenttime
) > max_height
/2)
1268 gdk_draw_layout_with_colors(drawing
->vertical_ruler
->window
,
1269 drawing
->ruler_gc_butt
,
1271 (drawing
->vertical_ruler
->allocation
.height
- ink_rect
.height
)/4,
1272 layout
, &red
, &background
);
1275 gdk_draw_layout_with_colors(drawing
->vertical_ruler
->window
,
1276 drawing
->ruler_gc_butt
,
1278 ((drawing
->vertical_ruler
->allocation
.height
1279 - ink_rect
.height
)*3)/4,
1280 layout
, &red
, &background
);
1287 g_object_unref(layout
);