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,
20 /*****************************************************************************
21 * Hooks to be called by the main window *
22 *****************************************************************************/
25 /* Event hooks are the drawing hooks called during traceset read. They draw the
26 * icons, text, lines and background color corresponding to the events read.
28 * Two hooks are used for drawing : before_schedchange and after_schedchange hooks. The
29 * before_schedchange is called before the state update that occurs with an event and
30 * the after_schedchange hook is called after this state update.
32 * The before_schedchange hooks fulfill the task of drawing the visible objects that
33 * corresponds to the data accumulated by the after_schedchange hook.
35 * The after_schedchange hook accumulates the data that need to be shown on the screen
36 * (items) into a queue. Then, the next before_schedchange hook will draw what that
37 * queue contains. That's the Right Way (TM) of drawing items on the screen,
38 * because we need to draw the background first (and then add icons, text, ...
39 * over it), but we only know the length of a background region once the state
40 * corresponding to it is over, which happens to be at the next before_schedchange
43 * We also have a hook called at the end of a chunk to draw the information left
44 * undrawn in each process queue. We use the current time as end of
52 //#define PANGO_ENABLE_BACKEND
60 //#include <pango/pango.h>
62 #include <ltt/event.h>
65 #include <ltt/trace.h>
67 #include <lttv/lttv.h>
68 #include <lttv/hook.h>
69 #include <lttv/state.h>
70 #include <lttvwindow/lttvwindow.h>
71 #include <lttvwindow/lttvwindowtraces.h>
72 #include <lttvwindow/support.h>
75 #include "histoeventhooks.h"
77 #include "histobuttonwidget.h"
78 #include "histodrawing.h"
81 #define MAX_PATH_LEN 256
82 #define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
84 // fixed #define TRACE_NUMBER 0
85 #define EXTRA_ALLOC 1024 // pixels
87 /* Action to do when background computation completed.
89 * Wait for all the awaited computations to be over.
92 static gint
histo_background_ready(void *hook_data
, void *call_data
)
94 HistoControlFlowData
*histocontrol_flow_data
= (HistoControlFlowData
*)hook_data
;
95 LttvTrace
*trace
= (LttvTrace
*)call_data
;
97 histoDrawing_t
*drawing
= histocontrol_flow_data
->drawing
;
98 histocontrol_flow_data
->background_info_waiting
--;
100 if(histocontrol_flow_data
->background_info_waiting
== 0) {
101 g_message("Histocontrol flow viewer : background computation data ready.");
103 histo_drawing_clear(drawing
,0,drawing
->width
);
105 gtk_widget_set_size_request(drawing
->drawing_area
,
107 histo_redraw_notify(histocontrol_flow_data
, NULL
);
114 /* Request background computation. Verify if it is in progress or ready first.
115 * Only for each trace in the tab's traceset.
117 static void histo_request_background_data(HistoControlFlowData
*histocontrol_flow_data
)
119 LttvTracesetContext
* tsc
=
120 lttvwindow_get_traceset_context(histocontrol_flow_data
->tab
);
121 gint num_traces
= lttv_traceset_number(tsc
->ts
);
124 LttvTraceState
*tstate
;
126 LttvHooks
*histo_background_ready_hook
=
128 lttv_hooks_add(histo_background_ready_hook
, histo_background_ready
, histocontrol_flow_data
,
130 histocontrol_flow_data
->background_info_waiting
= 0;
132 for(i
=0;i
<num_traces
;i
++) {
133 trace
= lttv_traceset_get(tsc
->ts
, i
);
134 tstate
= LTTV_TRACE_STATE(tsc
->traces
[i
]);
136 if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace
)==FALSE
137 && !tstate
->has_precomputed_states
) {
139 if(lttvwindowtraces_get_in_progress(g_quark_from_string("state"),
141 /* We first remove requests that could have been done for the same
142 * information. Happens when two viewers ask for it before servicing
145 if(!lttvwindowtraces_background_request_find(trace
, "state"))
146 lttvwindowtraces_background_request_queue(
147 main_window_get_widget(histocontrol_flow_data
->tab
), trace
, "state");
148 lttvwindowtraces_background_notify_queue(histocontrol_flow_data
,
152 histo_background_ready_hook
);
153 histocontrol_flow_data
->background_info_waiting
++;
154 } else { /* in progress */
156 lttvwindowtraces_background_notify_current(histocontrol_flow_data
,
160 histo_background_ready_hook
);
161 histocontrol_flow_data
->background_info_waiting
++;
164 /* Data ready. Be its nature, this viewer doesn't need to have
165 * its data ready hook called there, because a background
166 * request is always linked with a redraw.
172 lttv_hooks_destroy(histo_background_ready_hook
);
176 * Histogram Viewer's constructor hook
178 * This constructor is given as a parameter to the menuitem and toolbar button
179 * registration. It creates the list.
180 * @param tab A pointer to the parent tab.
181 * @return The widget created.
184 h_guihistocontrolflow(LttvPlugin
*plugin
)
186 LttvPluginTab
*ptab
= LTTV_PLUGIN_TAB(plugin
);
187 g_info("h_guihistocontrolflow, %p", ptab
);
188 HistoControlFlowData
*histocontrol_flow_data
= guihistocontrolflow(ptab
) ;
190 Tab
*tab
= ptab
->tab
;
191 histocontrol_flow_data
->tab
= tab
;
193 // Unreg done in the GuiHistoControlFlow_Destructor
194 lttvwindow_register_traceset_notify(tab
,
195 histo_traceset_notify
,
196 histocontrol_flow_data
);
198 lttvwindow_register_time_window_notify(tab
,
199 histo_update_time_window_hook
,
200 histocontrol_flow_data
);
201 lttvwindow_register_current_time_notify(tab
,
202 histo_update_current_time_hook
,
203 histocontrol_flow_data
);
204 lttvwindow_register_redraw_notify(tab
,
206 histocontrol_flow_data
);
207 lttvwindow_register_continue_notify(tab
,
208 histo_continue_notify
,
209 histocontrol_flow_data
);
210 //added for histogram, enable filter:
211 lttvwindow_register_filter_notify(tab
,
212 histo_filter_changed
,histocontrol_flow_data
);
213 histocontrol_flow_data
->histo_main_win_filter
= lttvwindow_get_filter(tab
);
215 // histo_request_background_data(histocontrol_flow_data);
217 return guihistocontrolflow_get_widget(histocontrol_flow_data
) ;
223 /// added for histogram.
224 void histo_request_event( HistoControlFlowData
*histocontrol_flow_data
, guint x
, guint width
)
226 if(width
< 0) return ;
229 Tab
*tab
= histocontrol_flow_data
->tab
;
230 TimeWindow time_window
= lttvwindow_get_time_window( tab
);
231 LttTime time_start
, time_end
;
235 //find the tracehooks
236 LttvTracesetContext
*tsc
= lttvwindow_get_traceset_context(tab
);
238 LttvTraceset
*traceset
= tsc
->ts
;
239 nb_trace
= lttv_traceset_number(traceset
);
240 guint drawing_width
= histocontrol_flow_data
->drawing
->width
;
241 //start time for chunk.
242 histo_convert_pixels_to_time(drawing_width
, /*0*/x
, time_window
,
244 //end time for chunk.
245 histo_convert_pixels_to_time(drawing_width
,
246 /*width*/x
+width
,time_window
,
248 time_end
= ltt_time_add(time_end
, ltt_time_one
); // because main window
249 // doesn't deliver end time.
251 lttvwindow_events_request_remove_all(tab
,
252 histocontrol_flow_data
);
255 // LttvHooksById *histo_event_by_id = lttv_hooks_by_id_new();//if necessary for filter!
256 // FIXME : eventually request for more traces
257 // fixed for(i = 0; i<MIN(TRACE_NUMBER+1, nb_trace);i++) {
258 for(i
=0;i
<nb_trace
;i
++) {
259 //should be in the loop or before?
260 EventsRequest
*histo_events_request
= g_new(EventsRequest
, 1);
262 LttvHooks
*histo_before_trace_hooks
= lttv_hooks_new();
263 lttv_hooks_add(histo_before_trace_hooks
, histo_before_trace
,
264 histo_events_request
, LTTV_PRIO_DEFAULT
);
266 LttvHooks
*histo_count_event_hooks
= lttv_hooks_new();
267 lttv_hooks_add(histo_count_event_hooks
, histo_count_event
,
268 histo_events_request
, LTTV_PRIO_DEFAULT
);
270 LttvHooks
*histo_after_trace_hooks
= lttv_hooks_new();
271 lttv_hooks_add(histo_after_trace_hooks
, histo_after_trace
,
272 histo_events_request
, LTTV_PRIO_DEFAULT
);
275 LttvHooks
*histo_before_chunk_traceset
= lttv_hooks_new();
276 LttvHooks
*histo_after_chunk_traceset
= lttv_hooks_new();
278 lttv_hooks_add(histo_before_chunk_traceset
,
280 histo_events_request
,
283 lttv_hooks_add(histo_after_chunk_traceset
,
285 histo_events_request
,
287 ts
= (LttvTraceState
*)tsc
->traces
[i
];
288 // Fill the events request
289 histo_events_request
->owner
= histocontrol_flow_data
;
290 histo_events_request
->viewer_data
= histocontrol_flow_data
;
291 histo_events_request
->servicing
= FALSE
;
292 histo_events_request
->start_time
= time_start
;//time_window.start_time;
294 histo_events_request
->start_position
= NULL
;
295 histo_events_request
->stop_flag
= FALSE
;
296 histo_events_request
->end_time
= time_end
;//time_window.end_time;
298 histo_events_request
->num_events
= G_MAXUINT
;
299 histo_events_request
->end_position
= NULL
;
300 histo_events_request
->trace
= i
;
301 histo_events_request
->hooks
= NULL
;
302 histo_events_request
->before_chunk_traceset
= histo_before_chunk_traceset
;//NULL;
303 histo_events_request
->before_chunk_trace
= NULL
;
304 histo_events_request
->before_chunk_tracefile
= NULL
;
305 histo_events_request
->event
= histo_count_event_hooks
;
306 histo_events_request
->event_by_id
= NULL
;//histo_event_by_id;//NULL;
307 histo_events_request
->after_chunk_tracefile
= NULL
;
308 histo_events_request
->after_chunk_trace
= NULL
;
309 histo_events_request
->after_chunk_traceset
= histo_after_chunk_traceset
;//NULL;
310 histo_events_request
->before_request
= histo_before_trace_hooks
;
311 histo_events_request
->after_request
= histo_after_trace_hooks
;
313 lttvwindow_events_request(histocontrol_flow_data
->tab
, histo_events_request
);
318 //hook,added for histogram
319 int histo_count_event(void *hook_data
, void *call_data
){
321 guint x
;//time to pixel
322 guint i
;// number of events
327 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
328 HistoControlFlowData
*histocontrol_flow_data
= events_request
->viewer_data
;
330 histoDrawing_t
*drawing
= histocontrol_flow_data
->drawing
;
331 int width
= drawing
->width
;
333 g_info("Histogram: count_event() \n");
336 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
337 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
339 e
= ltt_tracefile_get_event(tfc
->tf
);
341 LttvFilter
*histo_filter
= histocontrol_flow_data
->histo_main_win_filter
;
342 if(histo_filter
!= NULL
&& histo_filter
->head
!= NULL
)
343 if(!lttv_filter_tree_parse(histo_filter
->head
,e
,tfc
->tf
,
344 tfc
->t_context
->t
,tfc
,NULL
,NULL
))
347 TimeWindow time_window
= lttvwindow_get_time_window(histocontrol_flow_data
->tab
);
348 event_time
= ltt_event_time(e
);
350 histo_convert_time_to_pixels(
355 element
= &g_array_index(histocontrol_flow_data
->number_of_process
, guint
, x
);
360 ///befor hook:Added for histogram
361 int histo_before_trace(void *hook_data
, void *call_data
){
363 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
364 HistoControlFlowData
*histocontrol_flow_data
= events_request
->viewer_data
;
366 histoDrawing_t
*drawing
= histocontrol_flow_data
->drawing
;
368 //in order to reset all of the array elements.
370 end
= MIN(histocontrol_flow_data
->number_of_process
->len
,drawing
->damage_end
);
371 for(i
=drawing
->damage_begin
/*0*/;
372 i
< end
/*histocontrol_flow_data->number_of_process->len*/;i
++)
374 g_array_index(histocontrol_flow_data
->number_of_process
, guint
, i
) = 0;
376 histo_drawing_clear(drawing
,drawing
->damage_begin
/*0*/,
377 drawing
->damage_end
- drawing
->damage_begin
/*drawing->width*/);
378 //g_array_free(histocontrol_flow_data->number_of_process,TRUE);
379 //histocontrol_flow_data->number_of_process =g_array_new (FALSE,
381 // sizeof(guint));//4 byte for guint
382 //g_array_set_size (histocontrol_flow_data->number_of_process,
383 // drawing->drawing_area->allocation.width);
384 // gtk_widget_set_size_request(drawing->drawing_area,-1,-1);
385 gtk_widget_queue_draw(drawing
->drawing_area
);
388 //after hook,added for histogram
389 int histo_after_trace(void *hook_data
, void *call_data
){
391 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
392 HistoControlFlowData
*histocontrol_flow_data
= events_request
->viewer_data
;
393 histoDrawing_t
*drawing
= histocontrol_flow_data
->drawing
;
394 guint x
, x_end
, width
;
395 LttTime end_time
= events_request
->end_time
;
396 TimeWindow time_window
=
397 lttvwindow_get_time_window(histocontrol_flow_data
->tab
);
399 g_debug("histo after trace");
401 histo_convert_time_to_pixels(
406 x
= drawing
->damage_begin
;
408 drawing
->damage_begin
= x
+width
;
409 histogram_show (histocontrol_flow_data
,x
,x_end
);
414 void histogram_show(HistoControlFlowData
*histocontrol_flow_data
,guint draw_begin
,
417 histoDrawing_t
*drawing
= histocontrol_flow_data
->drawing
;
418 GtkWidget
*drawingarea
= histo_drawing_get_drawing_area(drawing
);
419 guint width
= drawing
->width
;
420 guint height
= drawing
->height
;//drawingarea->allocation.height;
422 /* gdk_gc_set_line_attributes(drawing->gc,
428 histo_drawing_clear(drawing
,draw_begin
,draw_end
);
430 TimeWindow time_window
=
431 lttvwindow_get_time_window(histocontrol_flow_data
->tab
);
435 guint i
,line_src
,line_end
;
436 guint end_chunk
=MIN(draw_end
,(histocontrol_flow_data
->number_of_process
)->len
);
438 for (i
=draw_begin
/*0*/;i
<end_chunk
/* (histocontrol_flow_data->number_of_process)->len*/;i
++){
439 val
=g_array_index(histocontrol_flow_data
->number_of_process
,guint
,i
);
440 h_val
= height
-((height
*val
)/histocontrol_flow_data
->max_height
);
442 histo_convert_pixels_to_time(width
, i
,
445 histo_convert_pixels_to_time(width
, i
+1,
450 //check if zoom in is used and more than 1 pixel correspond to each 1nsec
451 //used for drawing point (not line) on the screen.
452 /* while (ltt_time_compare(t1,t2)==0)
454 histo_convert_pixels_to_time(width, i++,
457 histo_convert_pixels_to_time(width, i+1,
463 */ //replaced later for lines.
465 if(val
> drawing
->histo_control_flow_data
->max_height
){
466 //overlimit, yellow color
467 gdk_gc_set_foreground(drawing
->gc
,&histo_drawing_colors
[COL_WHITE
] );//COL_RUN_TRAP
468 gdk_draw_line (drawing
->pixmap
,
474 gdk_gc_set_foreground(drawing
->gc
,&histo_drawing_colors
[COL_RUN_USER_MODE
] );
475 gdk_draw_line (drawing
->pixmap
,
481 while ((ltt_time_compare(t1
,t2
)==0)&&(i
<end_chunk
))//-1 , i to be incremented later
485 if(val
> drawing
->histo_control_flow_data
->max_height
){
486 //overlimit, yellow color
487 gdk_gc_set_foreground(drawing
->gc
,
488 &histo_drawing_colors
[COL_RUN_TRAP
] );
489 gdk_draw_line (drawing
->pixmap
,
495 gdk_gc_set_foreground(drawing
->gc
,&histo_drawing_colors
[COL_RUN_USER_MODE
] );
496 gdk_draw_line (drawing
->pixmap
,
501 histo_convert_pixels_to_time(width
, i
,
505 histo_convert_pixels_to_time(width
, i
+1,
509 }//while (t1==t2)////
513 histo_drawing_update_vertical_ruler(drawing
);
514 gtk_widget_queue_draw_area ( drawing
->drawing_area
,
516 draw_end
-draw_begin
, drawing
->height
);
517 gdk_window_process_updates(drawingarea
->window
,TRUE
);
520 int histo_event_selected_hook(void *hook_data
, void *call_data
)
522 HistoControlFlowData
*histocontrol_flow_data
= (HistoControlFlowData
*) hook_data
;
523 guint
*event_number
= (guint
*) call_data
;
525 g_debug("DEBUG : event selected by main window : %u", *event_number
);
532 /* histo_before_schedchange_hook
534 * This function basically draw lines and icons. Two types of lines are drawn :
535 * one small (3 pixels?) representing the state of the process and the second
536 * type is thicker (10 pixels?) representing on which CPU a process is running
537 * (and this only in running state).
539 * Extremums of the lines :
540 * x_min : time of the last event context for this process kept in memory.
541 * x_max : time of the current event.
542 * y : middle of the process in the process list. The process is found in the
543 * list, therefore is it's position in pixels.
545 * The choice of lines'color is defined by the context of the last event for this
550 int histo_before_schedchange_hook(void *hook_data, void *call_data)
556 gint
histo_update_time_window_hook(void *hook_data
, void *call_data
)
558 HistoControlFlowData
*histocontrol_flow_data
= (HistoControlFlowData
*) hook_data
;
559 histoDrawing_t
*drawing
= histocontrol_flow_data
->drawing
;
561 const TimeWindowNotifyData
*histo_time_window_nofify_data
=
562 ((const TimeWindowNotifyData
*)call_data
);
564 TimeWindow
*histo_old_time_window
=
565 histo_time_window_nofify_data
->old_time_window
;
566 TimeWindow
*histo_new_time_window
=
567 histo_time_window_nofify_data
->new_time_window
;
570 histo_drawing_update_ruler(drawing
,
571 histo_new_time_window
);
573 /* Two cases : zoom in/out or scrolling */
575 /* In order to make sure we can reuse the old drawing, the scale must
576 * be the same and the new time interval being partly located in the
577 * currently shown time interval. (reuse is only for scrolling)
580 g_info("Old time window HOOK : %lu, %lu to %lu, %lu",
581 histo_old_time_window
->start_time
.tv_sec
,
582 histo_old_time_window
->start_time
.tv_nsec
,
583 histo_old_time_window
->time_width
.tv_sec
,
584 histo_old_time_window
->time_width
.tv_nsec
);
586 g_info("New time window HOOK : %lu, %lu to %lu, %lu",
587 histo_new_time_window
->start_time
.tv_sec
,
588 histo_new_time_window
->start_time
.tv_nsec
,
589 histo_new_time_window
->time_width
.tv_sec
,
590 histo_new_time_window
->time_width
.tv_nsec
);
592 //For Histo,redraw always except if zoom fit is pushed 2 times consequently
593 if( histo_new_time_window
->start_time
.tv_sec
== histo_old_time_window
->start_time
.tv_sec
594 && histo_new_time_window
->start_time
.tv_nsec
== histo_old_time_window
->start_time
.tv_nsec
595 && histo_new_time_window
->time_width
.tv_sec
== histo_old_time_window
->time_width
.tv_sec
596 && histo_new_time_window
->time_width
.tv_nsec
== histo_old_time_window
->time_width
.tv_nsec
)
600 histo_rectangle_pixmap (drawing
->drawing_area
->style
->black_gc
,
603 drawing
->width
,//+SAFETY, // do not overlap
606 drawing
->damage_begin
= 0;
607 drawing
->damage_end
= drawing
->width
;
609 gtk_widget_queue_draw(drawing
->drawing_area
);
610 histo_request_event(histocontrol_flow_data
,drawing
->damage_begin
,
611 drawing
->damage_end
- drawing
->damage_begin
);
613 gdk_window_process_updates(drawing
->drawing_area
->window
,TRUE
);
615 //show number of event at current time
617 histo_drawing_update_vertical_ruler(drawing
);
621 /*// if( histo_new_time_window->time_width.tv_sec == histo_old_time_window->time_width.tv_sec
622 && histo_new_time_window->time_width.tv_nsec == histo_old_time_window->time_width.tv_nsec)
624 // Same scale (scrolling)
627 while scrolling no matter far or near ,
628 right or left it's necessary to redraw whole screen!*/
629 /*// LttTime *ns = &histo_new_time_window->start_time;
630 LttTime *nw = &histo_new_time_window->time_width;
631 LttTime *os = &histo_old_time_window->start_time;
632 LttTime *ow = &histo_old_time_window->time_width;
633 LttTime histo_old_end = histo_old_time_window->end_time;
634 LttTime histo_new_end = histo_new_time_window->end_time;
636 //if(ns<os+w && os+w<ns+w)
637 //if(ns<histo_old_end && os<ns)
639 //added for histogram
640 gtk_widget_queue_draw(drawing->drawing_area);
642 drawing->damage_begin = 0;
643 drawing->damage_end = drawing->width;
645 //replaced for hisogram
646 histo_request_event(histocontrol_flow_data,drawing->damage_begin,
647 drawing->damage_end- drawing->damage_begin);
649 if(ltt_time_compare(*ns, histo_old_end) == -1
650 && ltt_time_compare(*os, *ns) == -1)
652 g_info("scrolling near right");
653 // Scroll right, keep right part of the screen
655 guint width = drawing->width;
656 histo_convert_time_to_pixels(
657 *histo_old_time_window,
662 // Copy old data to new location
663 //replaced for histogram:
664 histo_copy_pixmap_region(drawing,NULL,
665 drawing->drawing_area->style->black_gc,//drawing->gc,
668 0, 0, (drawing->width-x)
671 if(drawing->damage_begin == drawing->damage_end)
672 drawing->damage_begin = drawing->width-x;
674 drawing->damage_begin = 0;
676 drawing->damage_end = drawing->width;
678 //(histo) copy corresponding array region too:
681 for(i=0; i < histocontrol_flow_data->number_of_process->len-x;i++)
683 g_array_index(histocontrol_flow_data->number_of_process, guint, i) =
684 g_array_index(histocontrol_flow_data->number_of_process, guint, i+x);
687 // Clear the data request background, but not SAFETY
690 //not necessary for histo, because in before chunk ,it clears the area
691 /* histo_rectangle_pixmap (
692 drawing->drawing_area->style->black_gc,
694 drawing->damage_begin, 0,
695 drawing->damage_end - drawing->damage_begin, // do not overlap
698 /* gtk_widget_queue_draw(drawing->drawing_area);
699 //gtk_widget_queue_draw_area (drawing->drawing_area,
701 // histocontrol_flow_data->drawing->width,
702 // histocontrol_flow_data->drawing->height);
704 // Get new data for the rest.
705 //replaced for hisogram
706 histo_request_event(histocontrol_flow_data,drawing->damage_begin,
707 drawing->damage_end- drawing->damage_begin);
710 //if(ns<os && os<ns+w)
711 //if(ns<os && os<histo_new_end)
712 if(ltt_time_compare(*ns,*os) == -1
713 && ltt_time_compare(*os,histo_new_end) == -1)
715 g_info("scrolling near left");
716 // Scroll left, keep left part of the screen
718 guint width = drawing->width;
719 histo_convert_time_to_pixels(
720 *histo_new_time_window,
725 // Copy old data to new location
726 //replaced for histogram
728 histo_copy_pixmap_region(drawing,NULL,
729 drawing->drawing_area->style->black_gc,//drawing->gc,
733 //(histo) copy corresponding array region too:
735 for(i=histocontrol_flow_data->number_of_process->len; i > x-1;i--)
737 g_array_index(histocontrol_flow_data->number_of_process, guint, i) =
738 g_array_index(histocontrol_flow_data->number_of_process, guint, i-x);
741 if(drawing->damage_begin == drawing->damage_end)
742 drawing->damage_end = x;
744 drawing->damage_end =
747 drawing->damage_begin = 0;
750 //not necessary for histo, because in before chunk ,it clears the area
751 /* histo_rectangle_pixmap (drawing->drawing_area->style->black_gc,
753 drawing->damage_begin, 0,
754 drawing->damage_end - drawing->damage_begin, // do not overlap
757 /* gtk_widget_queue_draw(drawing->drawing_area);
758 //gtk_widget_queue_draw_area (drawing->drawing_area,
760 // histocontrol_flow_data->drawing->width,
761 // histocontrol_flow_data->drawing->height);
764 // Get new data for the rest.
766 //replaced for hisogram
767 histo_request_event(histocontrol_flow_data,drawing->damage_begin,
768 drawing->damage_end- drawing->damage_begin);
771 if(ltt_time_compare(*ns,*os) == 0)
773 g_info("not scrolling");
775 g_info("scrolling far");
776 // Cannot reuse any part of the screen : far jump
778 //not necessary for histo, because in before chunk ,it clears the area
779 /* histo_rectangle_pixmap (histocontrol_flow_data->drawing->drawing_area->style->black_gc,
782 histocontrol_flow_data->drawing->width,//+SAFETY, // do not overlap
785 //gtk_widget_queue_draw_area (drawing->drawing_area,
787 // histocontrol_flow_data->drawing->width,
788 // histocontrol_flow_data->drawing->height);
789 /* gtk_widget_queue_draw(drawing->drawing_area);
791 drawing->damage_begin = 0;
792 drawing->damage_end = histocontrol_flow_data->drawing->width;
794 histo_drawing_data_request(histocontrol_flow_data->drawing,
796 histocontrol_flow_data->drawing->width,
797 histocontrol_flow_data->drawing->height);*/
798 //replaced for hisogram
799 /* histo_request_event(histocontrol_flow_data,drawing->damage_begin,
800 drawing->damage_end- drawing->damage_begin);
805 // Different scale (zoom)
808 //not necessary for histo, because in before chunk ,it clears the area
810 histo_rectangle_pixmap (drawing->drawing_area->style->black_gc,
813 histocontrol_flow_data->drawing->width+SAFETY, // do not overlap
816 //gtk_widget_queue_draw_area (drawing->drawing_area,
818 // histocontrol_flow_data->drawing->width,
819 // histocontrol_flow_data->drawing->height);
820 /*// gtk_widget_queue_draw(drawing->drawing_area);
822 drawing->damage_begin = 0;
823 drawing->damage_end = drawing->width;
825 //replaced for hisogram
826 histo_request_event(histocontrol_flow_data,drawing->damage_begin,
827 drawing->damage_end- drawing->damage_begin);
830 // Update directly when scrolling
831 gdk_window_process_updates(drawing->drawing_area->window,
834 //show number of event at current time
836 histo_drawing_update_vertical_ruler(drawing);
838 //disabled for histogram, always redraw whole screen.
842 gint
histo_traceset_notify(void *hook_data
, void *call_data
)
844 HistoControlFlowData
*histocontrol_flow_data
= (HistoControlFlowData
*) hook_data
;
845 histoDrawing_t
*drawing
= histocontrol_flow_data
->drawing
;
847 if(unlikely(drawing
->gc
== NULL
)) {
850 if(drawing
->dotted_gc
== NULL
) {
854 histo_drawing_clear(drawing
,0,drawing
->width
);
857 for(i
=0;i
< histocontrol_flow_data
->number_of_process
->len
;i
++)
859 g_array_index(histocontrol_flow_data
->number_of_process
, guint
, i
) = 0;
861 gtk_widget_set_size_request(
862 drawing
->drawing_area
,
864 histo_redraw_notify(histocontrol_flow_data
, NULL
);
866 ///histo_request_background_data(histocontrol_flow_data);
871 gint
histo_redraw_notify(void *hook_data
, void *call_data
)
873 HistoControlFlowData
*histocontrol_flow_data
= (HistoControlFlowData
*) hook_data
;
874 histoDrawing_t
*drawing
= histocontrol_flow_data
->drawing
;
875 GtkWidget
*widget
= drawing
->drawing_area
;
877 drawing
->damage_begin
= 0;
878 drawing
->damage_end
= drawing
->width
;
880 // fun feature, to be separated someday...
882 histo_drawing_clear(drawing
,0,drawing
->width
);
884 gtk_widget_set_size_request(
885 drawing
->drawing_area
,
889 histo_rectangle_pixmap (widget
->style
->black_gc
,
892 drawing
->alloc_width
,
894 gtk_widget_queue_draw(widget
);
897 if(drawing
->damage_begin
< drawing
->damage_end
)
899 //replaced for histogram
900 histo_request_event(histocontrol_flow_data
,0,drawing
->width
);
904 //gtk_widget_queue_draw_area(drawing->drawing_area,
913 gint
histo_continue_notify(void *hook_data
, void *call_data
)
915 HistoControlFlowData
*histocontrol_flow_data
= (HistoControlFlowData
*) hook_data
;
916 histoDrawing_t
*drawing
= histocontrol_flow_data
->drawing
;
918 //g_assert(widget->allocation.width == drawing->damage_end);
920 if(drawing
->damage_begin
< drawing
->damage_end
)
922 histo_request_event(histocontrol_flow_data
,drawing
->damage_begin
,
923 drawing
->damage_end
-drawing
->damage_begin
);
930 gint
histo_update_current_time_hook(void *hook_data
, void *call_data
)
932 HistoControlFlowData
*histocontrol_flow_data
= (HistoControlFlowData
*)hook_data
;
933 histoDrawing_t
*drawing
= histocontrol_flow_data
->drawing
;
935 LttTime current_time
= *((LttTime
*)call_data
);
937 TimeWindow time_window
=
938 lttvwindow_get_time_window(histocontrol_flow_data
->tab
);
940 LttTime time_begin
= time_window
.start_time
;
941 LttTime width
= time_window
.time_width
;
944 guint64 time_ll
= ltt_time_to_uint64(width
);
945 time_ll
= time_ll
>> 1; /* divide by two */
946 half_width
= ltt_time_from_uint64(time_ll
);
948 LttTime time_end
= ltt_time_add(time_begin
, width
);
950 LttvTracesetContext
* tsc
=
951 lttvwindow_get_traceset_context(histocontrol_flow_data
->tab
);
953 LttTime trace_start
= tsc
->time_span
.start_time
;
954 LttTime trace_end
= tsc
->time_span
.end_time
;
956 g_info("Histogram: New current time HOOK : %lu, %lu", current_time
.tv_sec
,
957 current_time
.tv_nsec
);
961 /* If current time is inside time interval, just move the highlight
964 /* Else, we have to change the time interval. We have to tell it
965 * to the main window. */
966 /* The time interval change will take care of placing the current
967 * time at the center of the visible area, or nearest possible if we are
968 * at one end of the trace. */
971 if(ltt_time_compare(current_time
, time_begin
) < 0)
973 TimeWindow histo_new_time_window
;
975 if(ltt_time_compare(current_time
,
976 ltt_time_add(trace_start
,half_width
)) < 0)
977 time_begin
= trace_start
;
979 time_begin
= ltt_time_sub(current_time
,half_width
);
981 histo_new_time_window
.start_time
= time_begin
;
982 histo_new_time_window
.time_width
= width
;
983 histo_new_time_window
.time_width_double
= ltt_time_to_double(width
);
984 histo_new_time_window
.end_time
= ltt_time_add(time_begin
, width
);
986 lttvwindow_report_time_window(histocontrol_flow_data
->tab
, histo_new_time_window
);
988 else if(ltt_time_compare(current_time
, time_end
) > 0)
990 TimeWindow histo_new_time_window
;
992 if(ltt_time_compare(current_time
, ltt_time_sub(trace_end
, half_width
)) > 0)
993 time_begin
= ltt_time_sub(trace_end
,width
);
995 time_begin
= ltt_time_sub(current_time
,half_width
);
997 histo_new_time_window
.start_time
= time_begin
;
998 histo_new_time_window
.time_width
= width
;
999 histo_new_time_window
.time_width_double
= ltt_time_to_double(width
);
1000 histo_new_time_window
.end_time
= ltt_time_add(time_begin
, width
);
1002 lttvwindow_report_time_window(histocontrol_flow_data
->tab
, histo_new_time_window
);
1005 gtk_widget_queue_draw(drawing
->drawing_area
);
1007 /* Update directly when scrolling */
1008 gdk_window_process_updates(drawing
->drawing_area
->window
,
1011 histo_drawing_update_vertical_ruler(drawing
);
1016 gboolean
histo_filter_changed(void * hook_data
, void * call_data
)
1018 HistoControlFlowData
*histocontrol_flow_data
= (HistoControlFlowData
*)hook_data
;
1019 histoDrawing_t
*drawing
=histocontrol_flow_data
->drawing
;
1021 LttvTracesetContext
* tsc
=
1022 lttvwindow_get_traceset_context(histocontrol_flow_data
->tab
);
1024 histocontrol_flow_data
->histo_main_win_filter
=
1025 (LttvFilter
*)call_data
;
1026 //get_events(event_viewer_data->vadjust_c->value, event_viewer_data);
1027 gtk_widget_set_size_request(
1028 drawing
->drawing_area
,
1030 drawing
->damage_begin
= 0;
1031 drawing
->damage_end
= drawing
->width
;
1033 /* //done in, before request!
1034 histo_drawing_clear(drawing,0,drawing->width);
1036 for(i=0;i < histocontrol_flow_data->number_of_process->len;i++)
1038 g_array_index(histocontrol_flow_data->number_of_process, guint, i) = 0;
1041 histo_request_event(histocontrol_flow_data
,0,drawing
->width
);
1046 typedef struct _histo_ClosureData
{
1047 EventsRequest
*events_request
;
1048 LttvTracesetState
*tss
;
1051 } histo_ClosureData
;
1055 int histo_before_chunk(void *hook_data
, void *call_data
)
1057 EventsRequest
*histo_events_request
= (EventsRequest
*)hook_data
;
1058 LttvTracesetState
*histo_tss
= (LttvTracesetState
*)call_data
;
1059 HistoControlFlowData
*histo_cfd
= (HistoControlFlowData
*)histo_events_request
->viewer_data
;
1061 /* Desactivate sort */
1062 gtk_tree_sortable_set_sort_column_id(
1063 GTK_TREE_SORTABLE(cfd
->process_list
->list_store
),
1065 GTK_SORT_ASCENDING
);
1067 histo_drawing_chunk_begin(histo_events_request
, histo_tss
);
1072 /*int histo_before_request(void *hook_data, void *call_data)
1074 EventsRequest *events_request = (EventsRequest*)hook_data;
1075 LttvTracesetState *tss = (LttvTracesetState*)call_data;
1077 histo_drawing_data_request_begin(events_request, tss);
1085 * after request is necessary in addition of after chunk in order to draw
1086 * lines until the end of the screen. after chunk just draws lines until
1093 /*int histo_after_request(void *hook_data, void *call_data)
1104 int histo_after_chunk(void *hook_data
, void *call_data
)
1106 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
1107 HistoControlFlowData
*histocontrol_flow_data
= events_request
->viewer_data
;
1108 LttvTracesetState
*tss
= (LttvTracesetState
*)call_data
;
1109 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)call_data
;
1110 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1113 histoDrawing_t
*drawing
= histocontrol_flow_data
->drawing
;
1115 if(!histocontrol_flow_data
->chunk_has_begun
) return;
1116 histocontrol_flow_data
->chunk_has_begun
= TRUE
;
1119 end_time
= LTT_TIME_MIN(tfc
->timestamp
, events_request
->end_time
);
1120 else /* end of traceset, or position now out of request : end */
1121 end_time
= events_request
->end_time
;
1123 guint x
, x_end
, width
;
1125 TimeWindow time_window
=
1126 lttvwindow_get_time_window(histocontrol_flow_data
->tab
);
1128 g_debug("histo after chunk");
1130 histo_convert_time_to_pixels(
1135 x
= drawing
->damage_begin
;
1137 drawing
->damage_begin
= x
+width
;
1139 histogram_show (histocontrol_flow_data
,x
,x_end
);