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