4c11cf3dcf252dd7f7e14e98a34532f9af0025e0
[lttv.git] / lttv / modules / gui / histogram / histoeventhooks.c
1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2006 Parisa heidari (inspired from CFV by Mathieu Desnoyers)
3 *
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;
7 *
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.
12 *
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,
16 * MA 02111-1307, USA.
17 */
18
19
20 /*****************************************************************************
21 * Hooks to be called by the main window *
22 *****************************************************************************/
23
24
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.
27 *
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.
31 *
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.
34 *
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
41 * hook.
42 *
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
45 * line/background.
46 */
47
48 #ifdef HAVE_CONFIG_H
49 #include <config.h>
50 #endif
51
52 //#define PANGO_ENABLE_BACKEND
53 #include <gtk/gtk.h>
54 #include <gdk/gdk.h>
55 #include <glib.h>
56 #include <assert.h>
57 #include <string.h>
58 #include <stdio.h>
59
60 //#include <pango/pango.h>
61
62 #include <ltt/event.h>
63 #include <ltt/time.h>
64 #include <ltt/trace.h>
65
66 #include <lttv/lttv.h>
67 #include <lttv/hook.h>
68 #include <lttv/state.h>
69 #include <lttvwindow/lttvwindow.h>
70 #include <lttvwindow/lttvwindowtraces.h>
71 #include <lttvwindow/support.h>
72
73
74 #include "histoeventhooks.h"
75 #include "histocfv.h"
76 #include "histobuttonwidget.h"
77 #include "histodrawing.h"
78
79
80 #define MAX_PATH_LEN 256
81 #define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
82 //FIXME
83 // fixed #define TRACE_NUMBER 0
84 #define EXTRA_ALLOC 1024 // pixels
85
86 /*
87 * Most functions here are inspired from the controlflow module.
88 * Look in gui/controlflow/eventhooks.c if you need to add more functionality
89 */
90
91 /**
92 * Histogram Viewer's constructor hook
93 *
94 * This constructor is given as a parameter to the menuitem and toolbar button
95 * registration. It creates the list.
96 * @param tab A pointer to the parent tab.
97 * @return The widget created.
98 */
99 GtkWidget *
100 h_guihistocontrolflow(LttvPlugin *plugin)
101 {
102 LttvPluginTab *ptab = LTTV_PLUGIN_TAB(plugin);
103 g_info("h_guihistocontrolflow, %p", ptab);
104 HistoControlFlowData *histocontrol_flow_data = guihistocontrolflow(ptab) ;
105
106 Tab *tab = ptab->tab;
107 histocontrol_flow_data->tab = tab;
108
109 // Unreg done in the GuiHistoControlFlow_Destructor
110 lttvwindow_register_traceset_notify(tab,
111 histo_traceset_notify,
112 histocontrol_flow_data);
113
114 lttvwindow_register_time_window_notify(tab,
115 histo_update_time_window_hook,
116 histocontrol_flow_data);
117 lttvwindow_register_current_time_notify(tab,
118 histo_update_current_time_hook,
119 histocontrol_flow_data);
120 lttvwindow_register_redraw_notify(tab,
121 histo_redraw_notify,
122 histocontrol_flow_data);
123 lttvwindow_register_continue_notify(tab,
124 histo_continue_notify,
125 histocontrol_flow_data);
126 //added for histogram, enable filter:
127 lttvwindow_register_filter_notify(tab,
128 histo_filter_changed,histocontrol_flow_data );
129 histocontrol_flow_data->histo_main_win_filter = lttvwindow_get_filter(tab);
130
131 // histo_request_background_data(histocontrol_flow_data);
132
133 return guihistocontrolflow_get_widget(histocontrol_flow_data) ;
134
135 }
136
137
138
139 /// added for histogram.
140 void histo_request_event( HistoControlFlowData *histocontrol_flow_data, guint x, guint width)
141 {
142 if(width < 0) return ;
143
144 guint i, nb_trace;
145 Tab *tab = histocontrol_flow_data->tab;
146 TimeWindow time_window = lttvwindow_get_time_window( tab );
147 LttTime time_start, time_end;
148
149 //find the tracehooks
150 LttvTraceset *traceset = lttvwindow_get_traceset(tab);
151
152 nb_trace = lttv_traceset_number(traceset);
153 guint drawing_width= histocontrol_flow_data->drawing->width;
154 //start time for chunk.
155 histo_convert_pixels_to_time(drawing_width, /*0*/x, time_window,
156 &time_start);
157 //end time for chunk.
158 histo_convert_pixels_to_time(drawing_width,
159 /*width*/x+width,time_window,
160 &time_end);
161 time_end = ltt_time_add(time_end, ltt_time_one); // because main window
162 // doesn't deliver end time.
163
164 lttvwindow_events_request_remove_all(tab,
165 histocontrol_flow_data);
166
167
168 // LttvHooksById *histo_event_by_id = lttv_hooks_by_id_new();//if necessary for filter!
169 // FIXME : eventually request for more traces
170 // fixed for(i = 0; i<MIN(TRACE_NUMBER+1, nb_trace);i++) {
171 //TODO ybrosseau 2012-07-10: Just do one request
172 for(i=0;i<nb_trace;i++) {
173 //should be in the loop or before?
174 EventsRequest *histo_events_request = g_new(EventsRequest, 1);
175
176 LttvHooks *histo_before_trace_hooks = lttv_hooks_new();
177 lttv_hooks_add(histo_before_trace_hooks, histo_before_trace,
178 histo_events_request, LTTV_PRIO_DEFAULT);
179
180 LttvHooks *histo_count_event_hooks = lttv_hooks_new();
181 lttv_hooks_add(histo_count_event_hooks, histo_count_event,
182 histo_events_request, LTTV_PRIO_DEFAULT);
183
184 LttvHooks *histo_after_trace_hooks = lttv_hooks_new();
185 lttv_hooks_add(histo_after_trace_hooks, histo_after_trace,
186 histo_events_request, LTTV_PRIO_DEFAULT);
187
188 //for chunk:
189 LttvHooks *histo_before_chunk_traceset = lttv_hooks_new();
190 LttvHooks *histo_after_chunk_traceset = lttv_hooks_new();
191
192 lttv_hooks_add(histo_before_chunk_traceset,
193 histo_before_chunk,
194 histo_events_request,
195 LTTV_PRIO_DEFAULT);
196
197 lttv_hooks_add(histo_after_chunk_traceset,
198 histo_after_chunk,
199 histo_events_request,
200 LTTV_PRIO_DEFAULT);
201 // Fill the events request
202 histo_events_request->owner = histocontrol_flow_data;
203 histo_events_request->viewer_data = histocontrol_flow_data;
204 histo_events_request->servicing = FALSE;
205 histo_events_request->start_time = time_start;//time_window.start_time;
206
207 histo_events_request->start_position = NULL;
208 histo_events_request->stop_flag = FALSE;
209 histo_events_request->end_time = time_end;//time_window.end_time;
210
211 histo_events_request->num_events = G_MAXUINT;
212 histo_events_request->end_position = NULL;
213 histo_events_request->trace = i;
214 histo_events_request->hooks = NULL;
215 histo_events_request->before_chunk_traceset = histo_before_chunk_traceset;//NULL;
216 histo_events_request->before_chunk_trace = NULL;
217 histo_events_request->before_chunk_tracefile= NULL;
218 histo_events_request->event = histo_count_event_hooks;
219 histo_events_request->after_chunk_tracefile = NULL;
220 histo_events_request->after_chunk_trace = NULL;
221 histo_events_request->after_chunk_traceset = histo_after_chunk_traceset;//NULL;
222 histo_events_request->before_request = histo_before_trace_hooks;
223 histo_events_request->after_request = histo_after_trace_hooks;
224
225 lttvwindow_events_request(histocontrol_flow_data->tab, histo_events_request);
226 }
227 return;
228 }
229
230 //hook,added for histogram
231 int histo_count_event(void *hook_data, void *call_data){
232
233 guint x;//time to pixel
234 LttTime event_time;
235 LttvEvent *e;
236 guint *element;
237
238 EventsRequest *events_request = (EventsRequest*)hook_data;
239 HistoControlFlowData *histocontrol_flow_data = events_request->viewer_data;
240
241 histoDrawing_t *drawing = histocontrol_flow_data->drawing;
242 int width = drawing->width;
243
244 g_info("Histogram: count_event() \n");
245
246 e = (LttvEvent *)call_data;
247 #ifdef BABEL_CLEANUP
248 LttvFilter *histo_filter = histocontrol_flow_data->histo_main_win_filter;
249 if(histo_filter != NULL && histo_filter->head != NULL)
250 if(!lttv_filter_tree_parse(histo_filter->head,e,tfc->tf,
251 tfc->t_context->t,tfc,NULL,NULL))
252 return FALSE;
253 #endif
254 TimeWindow time_window = lttvwindow_get_time_window(histocontrol_flow_data->tab);
255 event_time = lttv_event_get_timestamp(e);
256
257 histo_convert_time_to_pixels(
258 time_window,
259 event_time,
260 width,
261 &x);
262 element = &g_array_index(histocontrol_flow_data->number_of_process, guint, x);
263 (*element)++;
264
265 return 0;
266 }
267 ///befor hook:Added for histogram
268 int histo_before_trace(void *hook_data, void *call_data){
269
270 EventsRequest *events_request = (EventsRequest*)hook_data;
271 HistoControlFlowData *histocontrol_flow_data = events_request->viewer_data;
272
273 histoDrawing_t *drawing = histocontrol_flow_data->drawing;
274
275 //in order to reset all of the array elements.
276 guint i,end;
277 end = MIN(histocontrol_flow_data->number_of_process->len,drawing->damage_end);
278 for(i=drawing->damage_begin/*0*/;
279 i < end/*histocontrol_flow_data->number_of_process->len*/;i++)
280 {
281 g_array_index(histocontrol_flow_data->number_of_process, guint, i) = 0;
282 }
283 histo_drawing_clear(drawing,drawing->damage_begin/*0*/,
284 drawing->damage_end - drawing->damage_begin/*drawing->width*/);
285 //g_array_free(histocontrol_flow_data->number_of_process,TRUE);
286 //histocontrol_flow_data->number_of_process =g_array_new (FALSE,
287 // TRUE,
288 // sizeof(guint));//4 byte for guint
289 //g_array_set_size (histocontrol_flow_data->number_of_process,
290 // drawing->drawing_area->allocation.width);
291 // gtk_widget_set_size_request(drawing->drawing_area,-1,-1);
292 gtk_widget_queue_draw(drawing->drawing_area);
293 return 0;
294 }
295 //after hook,added for histogram
296 int histo_after_trace(void *hook_data, void *call_data){
297
298 EventsRequest *events_request = (EventsRequest*)hook_data;
299 HistoControlFlowData *histocontrol_flow_data = events_request->viewer_data;
300 histoDrawing_t *drawing = histocontrol_flow_data->drawing;
301 guint x, x_end, width;
302 LttTime end_time = events_request->end_time;
303 TimeWindow time_window =
304 lttvwindow_get_time_window(histocontrol_flow_data->tab);
305
306 g_debug("histo after trace");
307
308 histo_convert_time_to_pixels(
309 time_window,
310 end_time,
311 drawing->width,
312 &x_end);
313 x = drawing->damage_begin;
314 width = x_end - x;
315 drawing->damage_begin = x+width;
316 histogram_show (histocontrol_flow_data,x,x_end);
317
318 return 0;
319 }
320 /* TODO ybrosseau 2012-03-15: Cleanup line_src */
321 void histogram_show(HistoControlFlowData *histocontrol_flow_data,guint draw_begin,
322 guint draw_end)
323 {
324 histoDrawing_t *drawing = histocontrol_flow_data->drawing;
325 GtkWidget *drawingarea= histo_drawing_get_drawing_area(drawing);
326 guint width = drawing->width;
327 guint height= drawing->height;//drawingarea->allocation.height;
328
329 /* gdk_gc_set_line_attributes(drawing->gc,
330 2,
331 GDK_LINE_SOLID,
332 GDK_CAP_BUTT,
333 GDK_JOIN_MITER);*/
334 //clean the area!
335 histo_drawing_clear(drawing,draw_begin,draw_end);
336 LttTime t1, t2;
337 TimeWindow time_window =
338 lttvwindow_get_time_window(histocontrol_flow_data->tab);
339
340 guint val, h_val;
341
342 guint i/*, line_src*/;
343 guint end_chunk=MIN(draw_end,(histocontrol_flow_data->number_of_process)->len);
344
345 for (i=draw_begin/*0*/;i<end_chunk/* (histocontrol_flow_data->number_of_process)->len*/;i++){
346 val=g_array_index(histocontrol_flow_data->number_of_process,guint,i);
347 h_val= height-((height*val)/histocontrol_flow_data->max_height);
348
349 histo_convert_pixels_to_time(width, i,
350 time_window,
351 &t1);
352 histo_convert_pixels_to_time(width, i+1,
353 time_window,
354 &t2);
355 /* line_src=i; */
356
357 //check if zoom in is used and more than 1 pixel correspond to each 1nsec
358 //used for drawing point (not line) on the screen.
359 /* while (ltt_time_compare(t1,t2)==0)
360 {
361 histo_convert_pixels_to_time(width, i++,
362 time_window,
363 &t1);
364 histo_convert_pixels_to_time(width, i+1,
365 time_window,
366 &t2);
367
368
369 }//while (t1==t2)
370 */ //replaced later for lines.
371
372 if(val > drawing->histo_control_flow_data->max_height){
373 //overlimit, yellow color
374 gdk_gc_set_foreground(drawing->gc,&histo_drawing_colors[COL_WHITE] );//COL_RUN_TRAP
375 gdk_draw_line (drawing->pixmap,
376 drawing->gc,
377 i/*line_src*/,1,
378 i,/*1*/height);
379 }
380 else{
381 gdk_gc_set_foreground(drawing->gc,&histo_drawing_colors[COL_RUN_USER_MODE] );
382 gdk_draw_line (drawing->pixmap,
383 drawing->gc,
384 i/*line_src*/,h_val,
385 i,/*h_val*/height);
386 }
387
388 while ((ltt_time_compare(t1,t2)==0)&&(i<end_chunk))//-1 , i to be incremented later
389 {////
390 i++;
391
392 if(val > drawing->histo_control_flow_data->max_height){
393 //overlimit, yellow color
394 gdk_gc_set_foreground(drawing->gc,
395 &histo_drawing_colors[COL_RUN_TRAP] );
396 gdk_draw_line (drawing->pixmap,
397 drawing->gc,
398 i,1,
399 i,height);
400 }
401 else{
402 gdk_gc_set_foreground(drawing->gc,&histo_drawing_colors[COL_RUN_USER_MODE] );
403 gdk_draw_line (drawing->pixmap,
404 drawing->gc,
405 i,h_val,
406 i,height);
407 }
408 histo_convert_pixels_to_time(width, i,
409 time_window,
410 &t1);
411 if(i<end_chunk-1){
412 histo_convert_pixels_to_time(width, i+1,
413 time_window,
414 &t2);
415 }
416 }//while (t1==t2)////
417
418 }
419
420 histo_drawing_update_vertical_ruler(drawing);
421 gtk_widget_queue_draw_area ( drawing->drawing_area,
422 draw_begin, 0,
423 draw_end-draw_begin, drawing->height);
424 gdk_window_process_updates(drawingarea->window,TRUE);
425 }
426
427 int histo_event_selected_hook(void *hook_data, void *call_data)
428 {
429 guint *event_number = (guint*) call_data;
430
431 g_debug("DEBUG : event selected by main window : %u", *event_number);
432
433 return 0;
434 }
435
436
437
438 /* histo_before_schedchange_hook
439 *
440 * This function basically draw lines and icons. Two types of lines are drawn :
441 * one small (3 pixels?) representing the state of the process and the second
442 * type is thicker (10 pixels?) representing on which CPU a process is running
443 * (and this only in running state).
444 *
445 * Extremums of the lines :
446 * x_min : time of the last event context for this process kept in memory.
447 * x_max : time of the current event.
448 * y : middle of the process in the process list. The process is found in the
449 * list, therefore is it's position in pixels.
450 *
451 * The choice of lines'color is defined by the context of the last event for this
452 * process.
453 */
454
455 /*
456 int histo_before_schedchange_hook(void *hook_data, void *call_data)
457 {
458 return 0;
459 }
460 */
461
462 gint histo_update_time_window_hook(void *hook_data, void *call_data)
463 {
464 HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData*) hook_data;
465 histoDrawing_t *drawing = histocontrol_flow_data->drawing;
466
467 const TimeWindowNotifyData *histo_time_window_nofify_data =
468 ((const TimeWindowNotifyData *)call_data);
469
470 TimeWindow *histo_old_time_window =
471 histo_time_window_nofify_data->old_time_window;
472 TimeWindow *histo_new_time_window =
473 histo_time_window_nofify_data->new_time_window;
474
475 // Update the ruler
476 histo_drawing_update_ruler(drawing,
477 histo_new_time_window);
478
479 /* Two cases : zoom in/out or scrolling */
480
481 /* In order to make sure we can reuse the old drawing, the scale must
482 * be the same and the new time interval being partly located in the
483 * currently shown time interval. (reuse is only for scrolling)
484 */
485
486 g_info("Old time window HOOK : %lu, %lu to %lu, %lu",
487 histo_old_time_window->start_time.tv_sec,
488 histo_old_time_window->start_time.tv_nsec,
489 histo_old_time_window->time_width.tv_sec,
490 histo_old_time_window->time_width.tv_nsec);
491
492 g_info("New time window HOOK : %lu, %lu to %lu, %lu",
493 histo_new_time_window->start_time.tv_sec,
494 histo_new_time_window->start_time.tv_nsec,
495 histo_new_time_window->time_width.tv_sec,
496 histo_new_time_window->time_width.tv_nsec);
497
498 //For Histo,redraw always except if zoom fit is pushed 2 times consequently
499 if( histo_new_time_window->start_time.tv_sec == histo_old_time_window->start_time.tv_sec
500 && histo_new_time_window->start_time.tv_nsec == histo_old_time_window->start_time.tv_nsec
501 && histo_new_time_window->time_width.tv_sec == histo_old_time_window->time_width.tv_sec
502 && histo_new_time_window->time_width.tv_nsec == histo_old_time_window->time_width.tv_nsec)
503 {
504 return 0;
505 }
506 histo_rectangle_pixmap (drawing->drawing_area->style->black_gc,
507 TRUE,
508 0, 0,
509 drawing->width,//+SAFETY, // do not overlap
510 -1,drawing);
511
512 drawing->damage_begin = 0;
513 drawing->damage_end = drawing->width;
514
515 gtk_widget_queue_draw(drawing->drawing_area);
516 histo_request_event(histocontrol_flow_data,drawing->damage_begin,
517 drawing->damage_end- drawing->damage_begin);
518
519 gdk_window_process_updates(drawing->drawing_area->window,TRUE);
520
521 //show number of event at current time
522
523 histo_drawing_update_vertical_ruler(drawing);
524 return 0;
525 }
526
527 gint histo_traceset_notify(void *hook_data, void *call_data)
528 {
529 HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData*) hook_data;
530 histoDrawing_t *drawing = histocontrol_flow_data->drawing;
531
532 if(unlikely(drawing->gc == NULL)) {
533 return FALSE;
534 }
535 if(drawing->dotted_gc == NULL) {
536 return FALSE;
537 }
538
539 histo_drawing_clear(drawing,0,drawing->width);
540
541 guint i;
542 for(i=0;i < histocontrol_flow_data->number_of_process->len;i++)
543 {
544 g_array_index(histocontrol_flow_data->number_of_process, guint, i) = 0;
545 }
546 gtk_widget_set_size_request(
547 drawing->drawing_area,
548 -1, -1);
549 histo_redraw_notify(histocontrol_flow_data, NULL);
550
551 ///histo_request_background_data(histocontrol_flow_data);
552
553 return FALSE;
554 }
555
556 gint histo_redraw_notify(void *hook_data, void *call_data)
557 {
558 HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData*) hook_data;
559 histoDrawing_t *drawing = histocontrol_flow_data->drawing;
560 GtkWidget *widget = drawing->drawing_area;
561
562 drawing->damage_begin = 0;
563 drawing->damage_end = drawing->width;
564
565 // fun feature, to be separated someday...
566
567 histo_drawing_clear(drawing,0,drawing->width);
568
569 gtk_widget_set_size_request(
570 drawing->drawing_area,
571 -1, -1);
572 // Clear the images
573
574 histo_rectangle_pixmap (widget->style->black_gc,
575 TRUE,
576 0, 0,
577 drawing->alloc_width,
578 -1,drawing);
579 gtk_widget_queue_draw(widget);
580
581
582 if(drawing->damage_begin < drawing->damage_end)
583 {
584 //replaced for histogram
585 histo_request_event(histocontrol_flow_data,0,drawing->width);
586 }
587
588
589 //gtk_widget_queue_draw_area(drawing->drawing_area,
590 // 0,0,
591 // drawing->width,
592 // drawing->height);
593 return FALSE;
594
595 }
596
597
598 gint histo_continue_notify(void *hook_data, void *call_data)
599 {
600 HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData*) hook_data;
601 histoDrawing_t *drawing = histocontrol_flow_data->drawing;
602
603 //g_assert(widget->allocation.width == drawing->damage_end);
604
605 if(drawing->damage_begin < drawing->damage_end)
606 {
607 histo_request_event(histocontrol_flow_data,drawing->damage_begin,
608 drawing->damage_end-drawing->damage_begin);
609 }
610
611 return FALSE;
612 }
613
614
615 gint histo_update_current_time_hook(void *hook_data, void *call_data)
616 {
617 HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData*)hook_data;
618 histoDrawing_t *drawing = histocontrol_flow_data->drawing;
619
620 LttTime current_time = *((LttTime*)call_data);
621
622 TimeWindow time_window =
623 lttvwindow_get_time_window(histocontrol_flow_data->tab);
624
625 LttTime time_begin = time_window.start_time;
626 LttTime width = time_window.time_width;
627 LttTime half_width;
628 {
629 guint64 time_ll = ltt_time_to_uint64(width);
630 time_ll = time_ll >> 1; /* divide by two */
631 half_width = ltt_time_from_uint64(time_ll);
632 }
633 LttTime time_end = ltt_time_add(time_begin, width);
634
635 LttvTraceset *traceset =
636 lttvwindow_get_traceset(histocontrol_flow_data->tab);
637 TimeInterval time_span = lttv_traceset_get_time_span_real(traceset);
638
639 LttTime trace_start = time_span.start_time;
640 LttTime trace_end = time_span.end_time;
641
642 g_info("Histogram: New current time HOOK : %lu, %lu", current_time.tv_sec,
643 current_time.tv_nsec);
644
645
646
647 /* If current time is inside time interval, just move the highlight
648 * bar */
649
650 /* Else, we have to change the time interval. We have to tell it
651 * to the main window. */
652 /* The time interval change will take care of placing the current
653 * time at the center of the visible area, or nearest possible if we are
654 * at one end of the trace. */
655
656
657 if(ltt_time_compare(current_time, time_begin) < 0)
658 {
659 TimeWindow histo_new_time_window;
660
661 if(ltt_time_compare(current_time,
662 ltt_time_add(trace_start,half_width)) < 0)
663 time_begin = trace_start;
664 else
665 time_begin = ltt_time_sub(current_time,half_width);
666
667 histo_new_time_window.start_time = time_begin;
668 histo_new_time_window.time_width = width;
669 histo_new_time_window.time_width_double = ltt_time_to_double(width);
670 histo_new_time_window.end_time = ltt_time_add(time_begin, width);
671
672 lttvwindow_report_time_window(histocontrol_flow_data->tab, histo_new_time_window);
673 }
674 else if(ltt_time_compare(current_time, time_end) > 0)
675 {
676 TimeWindow histo_new_time_window;
677
678 if(ltt_time_compare(current_time, ltt_time_sub(trace_end, half_width)) > 0)
679 time_begin = ltt_time_sub(trace_end,width);
680 else
681 time_begin = ltt_time_sub(current_time,half_width);
682
683 histo_new_time_window.start_time = time_begin;
684 histo_new_time_window.time_width = width;
685 histo_new_time_window.time_width_double = ltt_time_to_double(width);
686 histo_new_time_window.end_time = ltt_time_add(time_begin, width);
687
688 lttvwindow_report_time_window(histocontrol_flow_data->tab, histo_new_time_window);
689
690 }
691 gtk_widget_queue_draw(drawing->drawing_area);
692
693 /* Update directly when scrolling */
694 gdk_window_process_updates(drawing->drawing_area->window,
695 TRUE);
696
697 histo_drawing_update_vertical_ruler(drawing);
698
699 return 0;
700 }
701
702 gboolean histo_filter_changed(void * hook_data, void * call_data)
703 {
704 HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData*)hook_data;
705 histoDrawing_t *drawing =histocontrol_flow_data->drawing;
706
707 histocontrol_flow_data->histo_main_win_filter =
708 (LttvFilter*)call_data;
709 //get_events(event_viewer_data->vadjust_c->value, event_viewer_data);
710 gtk_widget_set_size_request(
711 drawing->drawing_area,
712 -1, -1);
713 drawing->damage_begin = 0;
714 drawing->damage_end = drawing->width;
715
716 /* //done in, before request!
717 histo_drawing_clear(drawing,0,drawing->width);
718 guint i;
719 for(i=0;i < histocontrol_flow_data->number_of_process->len;i++)
720 {
721 g_array_index(histocontrol_flow_data->number_of_process, guint, i) = 0;
722 }*/
723
724 histo_request_event(histocontrol_flow_data,0,drawing->width);
725
726 return FALSE;
727 }
728
729 typedef struct _histo_ClosureData {
730 EventsRequest *events_request;
731 LttvTraceset *traceset;
732 LttTime end_time;
733 guint x_end;
734 } histo_ClosureData;
735
736
737
738 int histo_before_chunk(void *hook_data, void *call_data)
739 {
740 EventsRequest *histo_events_request = (EventsRequest*)hook_data;
741 LttvTraceset *histo_traceset = (LttvTraceset*)call_data;
742 #if 0
743 /* Desactivate sort */
744 gtk_tree_sortable_set_sort_column_id(
745 GTK_TREE_SORTABLE(cfd->process_list->list_store),
746 TRACE_COLUMN,
747 GTK_SORT_ASCENDING);
748 #endif //0
749 histo_drawing_chunk_begin(histo_events_request, histo_traceset);
750
751 return 0;
752 }
753
754 /*int histo_before_request(void *hook_data, void *call_data)
755 {
756 EventsRequest *events_request = (EventsRequest*)hook_data;
757 LttvTracesetState *tss = (LttvTracesetState*)call_data;
758
759 histo_drawing_data_request_begin(events_request, tss);
760
761 return 0;
762 }
763 */
764
765
766 /*
767 * after request is necessary in addition of after chunk in order to draw
768 * lines until the end of the screen. after chunk just draws lines until
769 * the last event.
770 *
771 * for each process
772 * draw closing line
773 * expose
774 */
775 /*int histo_after_request(void *hook_data, void *call_data)
776 {
777 return 0;
778 }
779 */
780 /*
781 * for each process
782 * draw closing line
783 * expose
784 */
785
786 int histo_after_chunk(void *hook_data, void *call_data)
787 {
788 EventsRequest *events_request = (EventsRequest*)hook_data;
789 HistoControlFlowData *histocontrol_flow_data = events_request->viewer_data;
790 LttvTraceset *traceset = (LttvTraceset*)call_data;
791
792 LttTime end_time;
793
794 histoDrawing_t *drawing = histocontrol_flow_data->drawing;
795
796 if(!histocontrol_flow_data->chunk_has_begun)
797 return 0;
798
799 histocontrol_flow_data->chunk_has_begun = TRUE;
800
801 #ifdef BABEL_CLEANUP
802 if(tfc != NULL)
803 end_time = LTT_TIME_MIN(tfc->timestamp, events_request->end_time);
804 else /* end of traceset, or position now out of request : end */
805 #endif
806 end_time = events_request->end_time;
807
808 guint x, x_end, width;
809
810 TimeWindow time_window =
811 lttvwindow_get_time_window(histocontrol_flow_data->tab);
812
813 g_debug("histo after chunk");
814
815 histo_convert_time_to_pixels(
816 time_window,
817 end_time,
818 drawing->width,
819 &x_end);
820 x = drawing->damage_begin;
821 width = x_end - x;
822 drawing->damage_begin = x+width;
823
824 histogram_show (histocontrol_flow_data,x,x_end);
825
826 return 0;
827 }
828
This page took 0.044531 seconds and 3 git commands to generate.