Add Histogram
[lttv.git] / ltt / branches / poly / lttv / modules / gui / histogram / histoeventhooks.c
CommitLineData
1684ba2e 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/type.h>
65#include <ltt/trace.h>
66
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>
73
74
75#include "histoeventhooks.h"
76#include "histocfv.h"
77#include "histobuttonwidget.h"
78#include "histodrawing.h"
79
80
81#define MAX_PATH_LEN 256
82#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
83//FIXME
84#define TRACE_NUMBER 0
85#define EXTRA_ALLOC 1024 // pixels
86
87/* Action to do when background computation completed.
88 *
89 * Wait for all the awaited computations to be over.
90 */
91
92static gint histo_background_ready(void *hook_data, void *call_data)
93{
94 HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData *)hook_data;
95 LttvTrace *trace = (LttvTrace*)call_data;
96
97 histoDrawing_t *drawing = histocontrol_flow_data->drawing;
98 histocontrol_flow_data->background_info_waiting--;
99
100 if(histocontrol_flow_data->background_info_waiting == 0) {
101 g_message("Histocontrol flow viewer : background computation data ready.");
102
103 histo_drawing_clear(drawing,0,drawing->width);
104
105 gtk_widget_set_size_request(drawing->drawing_area,
106 -1, -1);
107 histo_redraw_notify(histocontrol_flow_data, NULL);
108 }
109
110 return 0;
111}
112
113
114/* Request background computation. Verify if it is in progress or ready first.
115 * Only for each trace in the tab's traceset.
116 */
117static void histo_request_background_data(HistoControlFlowData *histocontrol_flow_data)
118{
119 LttvTracesetContext * tsc =
120 lttvwindow_get_traceset_context(histocontrol_flow_data->tab);
121 gint num_traces = lttv_traceset_number(tsc->ts);
122 gint i;
123 LttvTrace *trace;
124
125 LttvHooks *histo_background_ready_hook =
126 lttv_hooks_new();
127 lttv_hooks_add(histo_background_ready_hook, histo_background_ready, histocontrol_flow_data,
128 LTTV_PRIO_DEFAULT);
129 histocontrol_flow_data->background_info_waiting = 0;
130
131 for(i=0;i<num_traces;i++) {
132 trace = lttv_traceset_get(tsc->ts, i);
133
134 if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace)==FALSE) {
135
136 if(lttvwindowtraces_get_in_progress(g_quark_from_string("state"),
137 trace) == FALSE) {
138 /* We first remove requests that could have been done for the same
139 * information. Happens when two viewers ask for it before servicing
140 * starts.
141 */
142 if(!lttvwindowtraces_background_request_find(trace, "state"))
143 lttvwindowtraces_background_request_queue(
144 main_window_get_widget(histocontrol_flow_data->tab), trace, "state");
145 lttvwindowtraces_background_notify_queue(histocontrol_flow_data,
146 trace,
147 ltt_time_infinite,
148 NULL,
149 histo_background_ready_hook);
150 histocontrol_flow_data->background_info_waiting++;
151 } else { /* in progress */
152
153 lttvwindowtraces_background_notify_current(histocontrol_flow_data,
154 trace,
155 ltt_time_infinite,
156 NULL,
157 histo_background_ready_hook);
158 histocontrol_flow_data->background_info_waiting++;
159 }
160 } else {
161 /* Data ready. Be its nature, this viewer doesn't need to have
162 * its data ready hook called there, because a background
163 * request is always linked with a redraw.
164 */
165 }
166
167 }
168
169 lttv_hooks_destroy(histo_background_ready_hook);
170}
171
172/**
173 * Histogram Viewer's constructor hook
174 *
175 * This constructor is given as a parameter to the menuitem and toolbar button
176 * registration. It creates the list.
177 * @param tab A pointer to the parent tab.
178 * @return The widget created.
179 */
180GtkWidget *
181h_guihistocontrolflow(Tab *tab)
182{
183 g_info("h_guihistocontrolflow, %p", tab);
184 HistoControlFlowData *histocontrol_flow_data = guihistocontrolflow(tab) ;
185
186 histocontrol_flow_data->tab = tab;
187
188 // Unreg done in the GuiHistoControlFlow_Destructor
189 lttvwindow_register_traceset_notify(tab,
190 histo_traceset_notify,
191 histocontrol_flow_data);
192
193 lttvwindow_register_time_window_notify(tab,
194 histo_update_time_window_hook,
195 histocontrol_flow_data);
196 lttvwindow_register_current_time_notify(tab,
197 histo_update_current_time_hook,
198 histocontrol_flow_data);
199 lttvwindow_register_redraw_notify(tab,
200 histo_redraw_notify,
201 histocontrol_flow_data);
202 lttvwindow_register_continue_notify(tab,
203 histo_continue_notify,
204 histocontrol_flow_data);
205 //added for histogram, enable filter:
206 lttvwindow_register_filter_notify(tab,
207 histo_filter_changed,histocontrol_flow_data );
208 histocontrol_flow_data->histo_main_win_filter = lttvwindow_get_filter(tab);
209
210// histo_request_background_data(histocontrol_flow_data);
211
212 return guihistocontrolflow_get_widget(histocontrol_flow_data) ;
213
214}
215
216
217
218/// added for histogram.
219void histo_request_event( HistoControlFlowData *histocontrol_flow_data, guint x, guint width)
220{
221 if(width < 0) return ;
222
223 guint i, nb_trace;
224 Tab *tab = histocontrol_flow_data->tab;
225 TimeWindow time_window = lttvwindow_get_time_window( tab );
226 LttTime time_start, time_end;
227
228 LttvTraceState *ts;
229
230 //find the tracehooks
231 LttvTracesetContext *tsc = lttvwindow_get_traceset_context(tab);
232
233 LttvTraceset *traceset = tsc->ts;
234 nb_trace = lttv_traceset_number(traceset);
235 guint drawing_width= histocontrol_flow_data->drawing->width;
236//start time for chunk.
237 histo_convert_pixels_to_time(drawing_width, /*0*/x, time_window,
238 &time_start);
239//end time for chunk.
240 histo_convert_pixels_to_time(drawing_width,
241 /*width*/x+width,time_window,
242 &time_end);
243 time_end = ltt_time_add(time_end, ltt_time_one); // because main window
244 // doesn't deliver end time.
245
246 lttvwindow_events_request_remove_all(tab,
247 histocontrol_flow_data);
248
249
250 // LttvHooksById *histo_event_by_id = lttv_hooks_by_id_new();//if necessary for filter!
251 // FIXME : eventually request for more traces
252 for(i = 0; i<MIN(TRACE_NUMBER+1, nb_trace);i++)
253 {
254 //should be in the loop or before?
255 EventsRequest *histo_events_request = g_new(EventsRequest, 1);
256
257 LttvHooks *histo_before_trace_hooks = lttv_hooks_new();
258 lttv_hooks_add(histo_before_trace_hooks, histo_before_trace,
259 histo_events_request, LTTV_PRIO_DEFAULT);
260
261 LttvHooks *histo_count_event_hooks = lttv_hooks_new();
262 lttv_hooks_add(histo_count_event_hooks, histo_count_event,
263 histo_events_request, LTTV_PRIO_DEFAULT);
264
265 LttvHooks *histo_after_trace_hooks = lttv_hooks_new();
266 lttv_hooks_add(histo_after_trace_hooks, histo_after_trace,
267 histo_events_request, LTTV_PRIO_DEFAULT);
268
269 //for chunk:
270 LttvHooks *histo_before_chunk_traceset = lttv_hooks_new();
271 LttvHooks *histo_after_chunk_traceset = lttv_hooks_new();
272
273 lttv_hooks_add(histo_before_chunk_traceset,
274 histo_before_chunk,
275 histo_events_request,
276 LTTV_PRIO_DEFAULT);
277
278 lttv_hooks_add(histo_after_chunk_traceset,
279 histo_after_chunk,
280 histo_events_request,
281 LTTV_PRIO_DEFAULT);
282 ts = (LttvTraceState *)tsc->traces[i];
283 // Fill the events request
284 histo_events_request->owner = histocontrol_flow_data;
285 histo_events_request->viewer_data = histocontrol_flow_data;
286 histo_events_request->servicing = FALSE;
287 histo_events_request->start_time = time_start;//time_window.start_time;
288
289 histo_events_request->start_position = NULL;
290 histo_events_request->stop_flag = FALSE;
291 histo_events_request->end_time = time_end;//time_window.end_time;
292
293 histo_events_request->num_events = G_MAXUINT;
294 histo_events_request->end_position = NULL;
295 histo_events_request->trace = i;
296 histo_events_request->hooks = NULL;
297 histo_events_request->before_chunk_traceset = histo_before_chunk_traceset;//NULL;
298 histo_events_request->before_chunk_trace = NULL;
299 histo_events_request->before_chunk_tracefile= NULL;
300 histo_events_request->event = histo_count_event_hooks;
301 histo_events_request->event_by_id = NULL;//histo_event_by_id;//NULL;
302 histo_events_request->after_chunk_tracefile = NULL;
303 histo_events_request->after_chunk_trace = NULL;
304 histo_events_request->after_chunk_traceset = histo_after_chunk_traceset;//NULL;
305 histo_events_request->before_request = histo_before_trace_hooks;
306 histo_events_request->after_request = histo_after_trace_hooks;
307
308 lttvwindow_events_request(histocontrol_flow_data->tab, histo_events_request);
309 }
310return;
311}
312
313//hook,added for histogram
314int histo_count_event(void *hook_data, void *call_data){
315
316 guint x;//time to pixel
317 guint i;// number of events
318 LttTime event_time;
319 LttEvent *e;
320 guint *element;
321
322 EventsRequest *events_request = (EventsRequest*)hook_data;
323 HistoControlFlowData *histocontrol_flow_data = events_request->viewer_data;
324
325 histoDrawing_t *drawing = histocontrol_flow_data->drawing;
326 int width = drawing->width;
327
328 g_info("Histogram: count_event() \n");
329
330
331 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
332 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
333
334 e = ltt_tracefile_get_event(tfc->tf);
335
336 LttvFilter *histo_filter = histocontrol_flow_data->histo_main_win_filter;
337 if(histo_filter != NULL && histo_filter->head != NULL)
338 if(!lttv_filter_tree_parse(histo_filter->head,e,tfc->tf,
339 tfc->t_context->t,tfc))
340 return FALSE;
341
342 TimeWindow time_window = lttvwindow_get_time_window(histocontrol_flow_data->tab);
343 event_time = ltt_event_time(e);
344
345 histo_convert_time_to_pixels(
346 time_window,
347 event_time,
348 width,
349 &x);
350 element = &g_array_index(histocontrol_flow_data->number_of_process, guint, x);
351 (*element)++;
352
353 return 0;
354}
355///befor hook:Added for histogram
356int histo_before_trace(void *hook_data, void *call_data){
357
358 EventsRequest *events_request = (EventsRequest*)hook_data;
359 HistoControlFlowData *histocontrol_flow_data = events_request->viewer_data;
360
361 histoDrawing_t *drawing = histocontrol_flow_data->drawing;
362
363//in order to reset all of the array elements.
364 guint i,end;
365 end = MIN(histocontrol_flow_data->number_of_process->len,drawing->damage_end);
366 for(i=drawing->damage_begin/*0*/;
367 i < end/*histocontrol_flow_data->number_of_process->len*/;i++)
368 {
369 g_array_index(histocontrol_flow_data->number_of_process, guint, i) = 0;
370 }
371 histo_drawing_clear(drawing,drawing->damage_begin/*0*/,
372 drawing->damage_end - drawing->damage_begin/*drawing->width*/);
373 //g_array_free(histocontrol_flow_data->number_of_process,TRUE);
374 //histocontrol_flow_data->number_of_process =g_array_new (FALSE,
375 // TRUE,
376 // sizeof(guint));//4 byte for guint
377 //g_array_set_size (histocontrol_flow_data->number_of_process,
378 // drawing->drawing_area->allocation.width);
379// gtk_widget_set_size_request(drawing->drawing_area,-1,-1);
380 gtk_widget_queue_draw(drawing->drawing_area);
381 return 0;
382}
383//after hook,added for histogram
384int histo_after_trace(void *hook_data, void *call_data){
385
386 EventsRequest *events_request = (EventsRequest*)hook_data;
387 HistoControlFlowData *histocontrol_flow_data = events_request->viewer_data;
388 histoDrawing_t *drawing = histocontrol_flow_data->drawing;
389 guint x, x_end, width;
390 LttTime end_time = events_request->end_time;
391 TimeWindow time_window =
392 lttvwindow_get_time_window(histocontrol_flow_data->tab);
393
394 g_debug("histo after trace");
395
396 histo_convert_time_to_pixels(
397 time_window,
398 end_time,
399 drawing->width,
400 &x_end);
401 x = drawing->damage_begin;
402 width = x_end - x;
403 drawing->damage_begin = x+width;
404 histogram_show (histocontrol_flow_data,x,x_end);
405
406 return 0;
407}
408
409void histogram_show(HistoControlFlowData *histocontrol_flow_data,guint draw_begin,
410 guint draw_end)
411{
412 histoDrawing_t *drawing = histocontrol_flow_data->drawing;
413 GtkWidget *drawingarea= histo_drawing_get_drawing_area(drawing);
414 guint width = drawing->width;
415 guint height= drawing->height;//drawingarea->allocation.height;
416
417 /* gdk_gc_set_line_attributes(drawing->gc,
418 2,
419 GDK_LINE_SOLID,
420 GDK_CAP_BUTT,
421 GDK_JOIN_MITER);*/
422//clean the area!
423 histo_drawing_clear(drawing,draw_begin,draw_end);
424 LttTime t1,t2;
425 TimeWindow time_window =
426 lttvwindow_get_time_window(histocontrol_flow_data->tab);
427
428 guint val,h_val;
429
430 guint i,line_src,line_end;
431 guint end_chunk=MIN(draw_end,(histocontrol_flow_data->number_of_process)->len);
432
433 for (i=draw_begin/*0*/;i<end_chunk/* (histocontrol_flow_data->number_of_process)->len*/;i++){
434 val=g_array_index(histocontrol_flow_data->number_of_process,guint,i);
435 h_val= height-((height*val)/histocontrol_flow_data->max_height);
436
437 histo_convert_pixels_to_time(width, i,
438 time_window,
439 &t1);
440 histo_convert_pixels_to_time(width, i+1,
441 time_window,
442 &t2);
443 line_src=i;
444
445//check if zoom in is used and more than 1 pixel correspond to each 1nsec
446//used for drawing point (not line) on the screen.
447/* while (ltt_time_compare(t1,t2)==0)
448 {
449 histo_convert_pixels_to_time(width, i++,
450 time_window,
451 &t1);
452 histo_convert_pixels_to_time(width, i+1,
453 time_window,
454 &t2);
455
456
457 }//while (t1==t2)
458*/ //replaced later for lines.
459
460 if(val > drawing->histo_control_flow_data->max_height){
461 //overlimit, yellow color
462 gdk_gc_set_foreground(drawing->gc,&histo_drawing_colors[COL_WHITE] );//COL_RUN_TRAP
463 gdk_draw_line (drawing->pixmap,
464 drawing->gc,
465 i/*line_src*/,1,
466 i,/*1*/height);
467 }
468 else{
469 gdk_gc_set_foreground(drawing->gc,&histo_drawing_colors[COL_RUN_USER_MODE] );
470 gdk_draw_line (drawing->pixmap,
471 drawing->gc,
472 i/*line_src*/,h_val,
473 i,/*h_val*/height);
474 }
475
476 while ((ltt_time_compare(t1,t2)==0)&&(i<end_chunk))//-1 , i to be incremented later
477 {////
478 i++;
479
480 if(val > drawing->histo_control_flow_data->max_height){
481 //overlimit, yellow color
482 gdk_gc_set_foreground(drawing->gc,
483 &histo_drawing_colors[COL_RUN_TRAP] );
484 gdk_draw_line (drawing->pixmap,
485 drawing->gc,
486 i,1,
487 i,height);
488 }
489 else{
490 gdk_gc_set_foreground(drawing->gc,&histo_drawing_colors[COL_RUN_USER_MODE] );
491 gdk_draw_line (drawing->pixmap,
492 drawing->gc,
493 i,h_val,
494 i,height);
495 }
496 histo_convert_pixels_to_time(width, i,
497 time_window,
498 &t1);
499 if(i<end_chunk-1){
500 histo_convert_pixels_to_time(width, i+1,
501 time_window,
502 &t2);
503 }
504 }//while (t1==t2)////
505
506 }
507
508 histo_drawing_update_vertical_ruler(drawing);
509 gtk_widget_queue_draw_area ( drawing->drawing_area,
510 draw_begin, 0,
511 draw_end-draw_begin, drawing->height);
512 gdk_window_process_updates(drawingarea->window,TRUE);
513}
514
515int histo_event_selected_hook(void *hook_data, void *call_data)
516{
517 HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData*) hook_data;
518 guint *event_number = (guint*) call_data;
519
520 g_debug("DEBUG : event selected by main window : %u", *event_number);
521
522 return 0;
523}
524
525
526
527/* histo_before_schedchange_hook
528 *
529 * This function basically draw lines and icons. Two types of lines are drawn :
530 * one small (3 pixels?) representing the state of the process and the second
531 * type is thicker (10 pixels?) representing on which CPU a process is running
532 * (and this only in running state).
533 *
534 * Extremums of the lines :
535 * x_min : time of the last event context for this process kept in memory.
536 * x_max : time of the current event.
537 * y : middle of the process in the process list. The process is found in the
538 * list, therefore is it's position in pixels.
539 *
540 * The choice of lines'color is defined by the context of the last event for this
541 * process.
542 */
543
544/*
545int histo_before_schedchange_hook(void *hook_data, void *call_data)
546{
547 return 0;
548}
549*/
550
551gint histo_update_time_window_hook(void *hook_data, void *call_data)
552{
553 HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData*) hook_data;
554 histoDrawing_t *drawing = histocontrol_flow_data->drawing;
555
556 const TimeWindowNotifyData *histo_time_window_nofify_data =
557 ((const TimeWindowNotifyData *)call_data);
558
559 TimeWindow *histo_old_time_window =
560 histo_time_window_nofify_data->old_time_window;
561 TimeWindow *histo_new_time_window =
562 histo_time_window_nofify_data->new_time_window;
563
564 // Update the ruler
565 histo_drawing_update_ruler(drawing,
566 histo_new_time_window);
567
568 /* Two cases : zoom in/out or scrolling */
569
570 /* In order to make sure we can reuse the old drawing, the scale must
571 * be the same and the new time interval being partly located in the
572 * currently shown time interval. (reuse is only for scrolling)
573 */
574
575 g_info("Old time window HOOK : %lu, %lu to %lu, %lu",
576 histo_old_time_window->start_time.tv_sec,
577 histo_old_time_window->start_time.tv_nsec,
578 histo_old_time_window->time_width.tv_sec,
579 histo_old_time_window->time_width.tv_nsec);
580
581 g_info("New time window HOOK : %lu, %lu to %lu, %lu",
582 histo_new_time_window->start_time.tv_sec,
583 histo_new_time_window->start_time.tv_nsec,
584 histo_new_time_window->time_width.tv_sec,
585 histo_new_time_window->time_width.tv_nsec);
586
587 //For Histo,redraw always except if zoom fit is pushed 2 times consequently
588 if( histo_new_time_window->start_time.tv_sec == histo_old_time_window->start_time.tv_sec
589 && histo_new_time_window->start_time.tv_nsec == histo_old_time_window->start_time.tv_nsec
590 && histo_new_time_window->time_width.tv_sec == histo_old_time_window->time_width.tv_sec
591 && histo_new_time_window->time_width.tv_nsec == histo_old_time_window->time_width.tv_nsec)
592 {
593 return 0;
594 }
595 histo_rectangle_pixmap (drawing->drawing_area->style->black_gc,
596 TRUE,
597 0, 0,
598 drawing->width,//+SAFETY, // do not overlap
599 -1,drawing);
600
601 drawing->damage_begin = 0;
602 drawing->damage_end = drawing->width;
603
604 gtk_widget_queue_draw(drawing->drawing_area);
605 histo_request_event(histocontrol_flow_data,drawing->damage_begin,
606 drawing->damage_end- drawing->damage_begin);
607
608 gdk_window_process_updates(drawing->drawing_area->window,TRUE);
609
610//show number of event at current time
611
612 histo_drawing_update_vertical_ruler(drawing);
613
614
615
616/*// if( histo_new_time_window->time_width.tv_sec == histo_old_time_window->time_width.tv_sec
617 && histo_new_time_window->time_width.tv_nsec == histo_old_time_window->time_width.tv_nsec)
618 {
619 // Same scale (scrolling)
620 g_info("scrolling");
621 /* For histogram,
622 while scrolling no matter far or near ,
623 right or left it's necessary to redraw whole screen!*/
624/*// LttTime *ns = &histo_new_time_window->start_time;
625 LttTime *nw = &histo_new_time_window->time_width;
626 LttTime *os = &histo_old_time_window->start_time;
627 LttTime *ow = &histo_old_time_window->time_width;
628 LttTime histo_old_end = histo_old_time_window->end_time;
629 LttTime histo_new_end = histo_new_time_window->end_time;
630 //if(ns<os+w<ns+w)
631 //if(ns<os+w && os+w<ns+w)
632 //if(ns<histo_old_end && os<ns)
633
634 //added for histogram
635 gtk_widget_queue_draw(drawing->drawing_area);
636
637 drawing->damage_begin = 0;
638 drawing->damage_end = drawing->width;
639
640 //replaced for hisogram
641 histo_request_event(histocontrol_flow_data,drawing->damage_begin,
642 drawing->damage_end- drawing->damage_begin);
643/*
644 if(ltt_time_compare(*ns, histo_old_end) == -1
645 && ltt_time_compare(*os, *ns) == -1)
646 {
647 g_info("scrolling near right");
648 // Scroll right, keep right part of the screen
649 guint x = 0;
650 guint width = drawing->width;
651 histo_convert_time_to_pixels(
652 *histo_old_time_window,
653 *ns,
654 width,
655 &x);
656
657 // Copy old data to new location
658 //replaced for histogram:
659 histo_copy_pixmap_region(drawing,NULL,
660 drawing->drawing_area->style->black_gc,//drawing->gc,
661 NULL,
662 x, 0,
663 0, 0, (drawing->width-x)
664 , -1);
665
666 if(drawing->damage_begin == drawing->damage_end)
667 drawing->damage_begin = drawing->width-x;
668 else
669 drawing->damage_begin = 0;
670
671 drawing->damage_end = drawing->width;
672
673//(histo) copy corresponding array region too:
674 guint i;
675
676 for(i=0; i < histocontrol_flow_data->number_of_process->len-x;i++)
677 {
678 g_array_index(histocontrol_flow_data->number_of_process, guint, i) =
679 g_array_index(histocontrol_flow_data->number_of_process, guint, i+x);
680 }
681
682 // Clear the data request background, but not SAFETY
683
684
685//not necessary for histo, because in before chunk ,it clears the area
686/* histo_rectangle_pixmap (
687 drawing->drawing_area->style->black_gc,
688 TRUE,
689 drawing->damage_begin, 0,
690 drawing->damage_end - drawing->damage_begin, // do not overlap
691 -1,drawing);
692*/
693 /* gtk_widget_queue_draw(drawing->drawing_area);
694 //gtk_widget_queue_draw_area (drawing->drawing_area,
695 // 0,0,
696 // histocontrol_flow_data->drawing->width,
697 // histocontrol_flow_data->drawing->height);
698
699 // Get new data for the rest.
700 //replaced for hisogram
701 histo_request_event(histocontrol_flow_data,drawing->damage_begin,
702 drawing->damage_end- drawing->damage_begin);
703 } else {
704 //if(ns<os<ns+w)
705 //if(ns<os && os<ns+w)
706 //if(ns<os && os<histo_new_end)
707 if(ltt_time_compare(*ns,*os) == -1
708 && ltt_time_compare(*os,histo_new_end) == -1)
709 {
710 g_info("scrolling near left");
711 // Scroll left, keep left part of the screen
712 guint x = 0;
713 guint width = drawing->width;
714 histo_convert_time_to_pixels(
715 *histo_new_time_window,
716 *os,
717 width,
718 &x);
719
720 // Copy old data to new location
721 //replaced for histogram
722
723 histo_copy_pixmap_region(drawing,NULL,
724 drawing->drawing_area->style->black_gc,//drawing->gc,
725 NULL,
726 0, 0,
727 x, 0, -1, -1);
728 //(histo) copy corresponding array region too:
729 guint i;
730 for(i=histocontrol_flow_data->number_of_process->len; i > x-1;i--)
731 {
732 g_array_index(histocontrol_flow_data->number_of_process, guint, i) =
733 g_array_index(histocontrol_flow_data->number_of_process, guint, i-x);
734 }
735
736 if(drawing->damage_begin == drawing->damage_end)
737 drawing->damage_end = x;
738 else
739 drawing->damage_end =
740 drawing->width;
741
742 drawing->damage_begin = 0;
743
744
745//not necessary for histo, because in before chunk ,it clears the area
746 /* histo_rectangle_pixmap (drawing->drawing_area->style->black_gc,
747 TRUE,
748 drawing->damage_begin, 0,
749 drawing->damage_end - drawing->damage_begin, // do not overlap
750 -1,drawing);
751*/
752 /* gtk_widget_queue_draw(drawing->drawing_area);
753 //gtk_widget_queue_draw_area (drawing->drawing_area,
754 // 0,0,
755 // histocontrol_flow_data->drawing->width,
756 // histocontrol_flow_data->drawing->height);
757
758
759 // Get new data for the rest.
760
761//replaced for hisogram
762 histo_request_event(histocontrol_flow_data,drawing->damage_begin,
763 drawing->damage_end- drawing->damage_begin);
764
765 } else {
766 if(ltt_time_compare(*ns,*os) == 0)
767 {
768 g_info("not scrolling");
769 } else {
770 g_info("scrolling far");
771 // Cannot reuse any part of the screen : far jump
772
773 //not necessary for histo, because in before chunk ,it clears the area
774 /* histo_rectangle_pixmap (histocontrol_flow_data->drawing->drawing_area->style->black_gc,
775 TRUE,
776 0, 0,
777 histocontrol_flow_data->drawing->width,//+SAFETY, // do not overlap
778 -1,drawing);
779*/
780 //gtk_widget_queue_draw_area (drawing->drawing_area,
781 // 0,0,
782 // histocontrol_flow_data->drawing->width,
783 // histocontrol_flow_data->drawing->height);
784/* gtk_widget_queue_draw(drawing->drawing_area);
785
786 drawing->damage_begin = 0;
787 drawing->damage_end = histocontrol_flow_data->drawing->width;
788/*
789 histo_drawing_data_request(histocontrol_flow_data->drawing,
790 0, 0,
791 histocontrol_flow_data->drawing->width,
792 histocontrol_flow_data->drawing->height);*/
793 //replaced for hisogram
794 /* histo_request_event(histocontrol_flow_data,drawing->damage_begin,
795 drawing->damage_end- drawing->damage_begin);
796 }
797 }
798 }
799 } else {
800 // Different scale (zoom)
801 g_info("zoom");
802
803 //not necessary for histo, because in before chunk ,it clears the area
804 /*
805 histo_rectangle_pixmap (drawing->drawing_area->style->black_gc,
806 TRUE,
807 0, 0,
808 histocontrol_flow_data->drawing->width+SAFETY, // do not overlap
809 -1,drawing);
810*/
811 //gtk_widget_queue_draw_area (drawing->drawing_area,
812 // 0,0,
813 // histocontrol_flow_data->drawing->width,
814 // histocontrol_flow_data->drawing->height);
815/*// gtk_widget_queue_draw(drawing->drawing_area);
816
817 drawing->damage_begin = 0;
818 drawing->damage_end = drawing->width;
819
820 //replaced for hisogram
821 histo_request_event(histocontrol_flow_data,drawing->damage_begin,
822 drawing->damage_end- drawing->damage_begin);
823 }
824
825 // Update directly when scrolling
826 gdk_window_process_updates(drawing->drawing_area->window,
827 TRUE);
828
829 //show number of event at current time
830
831 histo_drawing_update_vertical_ruler(drawing);
832*/
833//disabled for histogram, always redraw whole screen.
834 return 0;
835}
836
837gint histo_traceset_notify(void *hook_data, void *call_data)
838{
839 HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData*) hook_data;
840 histoDrawing_t *drawing = histocontrol_flow_data->drawing;
841
842 if(unlikely(drawing->gc == NULL)) {
843 return FALSE;
844 }
845 if(drawing->dotted_gc == NULL) {
846 return FALSE;
847 }
848
849 histo_drawing_clear(drawing,0,drawing->width);
850
851 guint i;
852 for(i=0;i < histocontrol_flow_data->number_of_process->len;i++)
853 {
854 g_array_index(histocontrol_flow_data->number_of_process, guint, i) = 0;
855 }
856 gtk_widget_set_size_request(
857 drawing->drawing_area,
858 -1, -1);
859 histo_redraw_notify(histocontrol_flow_data, NULL);
860
861 ///histo_request_background_data(histocontrol_flow_data);
862
863 return FALSE;
864}
865
866gint histo_redraw_notify(void *hook_data, void *call_data)
867{
868 HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData*) hook_data;
869 histoDrawing_t *drawing = histocontrol_flow_data->drawing;
870 GtkWidget *widget = drawing->drawing_area;
871
872 drawing->damage_begin = 0;
873 drawing->damage_end = drawing->width;
874
875 // fun feature, to be separated someday...
876
877 histo_drawing_clear(drawing,0,drawing->width);
878
879 gtk_widget_set_size_request(
880 drawing->drawing_area,
881 -1, -1);
882 // Clear the images
883
884 histo_rectangle_pixmap (widget->style->black_gc,
885 TRUE,
886 0, 0,
887 drawing->alloc_width,
888 -1,drawing);
889 gtk_widget_queue_draw(widget);
890
891
892 if(drawing->damage_begin < drawing->damage_end)
893 {
894 //replaced for histogram
895 histo_request_event(histocontrol_flow_data,0,drawing->width);
896 }
897
898
899 //gtk_widget_queue_draw_area(drawing->drawing_area,
900 // 0,0,
901 // drawing->width,
902 // drawing->height);
903 return FALSE;
904
905}
906
907
908gint histo_continue_notify(void *hook_data, void *call_data)
909{
910 HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData*) hook_data;
911 histoDrawing_t *drawing = histocontrol_flow_data->drawing;
912
913 //g_assert(widget->allocation.width == drawing->damage_end);
914
915 if(drawing->damage_begin < drawing->damage_end)
916 {
917 histo_request_event(histocontrol_flow_data,drawing->damage_begin,
918 drawing->damage_end-drawing->damage_begin);
919 }
920
921 return FALSE;
922}
923
924
925gint histo_update_current_time_hook(void *hook_data, void *call_data)
926{
927 HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData*)hook_data;
928 histoDrawing_t *drawing = histocontrol_flow_data->drawing;
929
930 LttTime current_time = *((LttTime*)call_data);
931
932 TimeWindow time_window =
933 lttvwindow_get_time_window(histocontrol_flow_data->tab);
934
935 LttTime time_begin = time_window.start_time;
936 LttTime width = time_window.time_width;
937 LttTime half_width;
938 {
939 guint64 time_ll = ltt_time_to_uint64(width);
940 time_ll = time_ll >> 1; /* divide by two */
941 half_width = ltt_time_from_uint64(time_ll);
942 }
943 LttTime time_end = ltt_time_add(time_begin, width);
944
945 LttvTracesetContext * tsc =
946 lttvwindow_get_traceset_context(histocontrol_flow_data->tab);
947
948 LttTime trace_start = tsc->time_span.start_time;
949 LttTime trace_end = tsc->time_span.end_time;
950
951 g_info("Histogram: New current time HOOK : %lu, %lu", current_time.tv_sec,
952 current_time.tv_nsec);
953
954
955
956 /* If current time is inside time interval, just move the highlight
957 * bar */
958
959 /* Else, we have to change the time interval. We have to tell it
960 * to the main window. */
961 /* The time interval change will take care of placing the current
962 * time at the center of the visible area, or nearest possible if we are
963 * at one end of the trace. */
964
965
966 if(ltt_time_compare(current_time, time_begin) < 0)
967 {
968 TimeWindow histo_new_time_window;
969
970 if(ltt_time_compare(current_time,
971 ltt_time_add(trace_start,half_width)) < 0)
972 time_begin = trace_start;
973 else
974 time_begin = ltt_time_sub(current_time,half_width);
975
976 histo_new_time_window.start_time = time_begin;
977 histo_new_time_window.time_width = width;
978 histo_new_time_window.time_width_double = ltt_time_to_double(width);
979 histo_new_time_window.end_time = ltt_time_add(time_begin, width);
980
981 lttvwindow_report_time_window(histocontrol_flow_data->tab, histo_new_time_window);
982 }
983 else if(ltt_time_compare(current_time, time_end) > 0)
984 {
985 TimeWindow histo_new_time_window;
986
987 if(ltt_time_compare(current_time, ltt_time_sub(trace_end, half_width)) > 0)
988 time_begin = ltt_time_sub(trace_end,width);
989 else
990 time_begin = ltt_time_sub(current_time,half_width);
991
992 histo_new_time_window.start_time = time_begin;
993 histo_new_time_window.time_width = width;
994 histo_new_time_window.time_width_double = ltt_time_to_double(width);
995 histo_new_time_window.end_time = ltt_time_add(time_begin, width);
996
997 lttvwindow_report_time_window(histocontrol_flow_data->tab, histo_new_time_window);
998
999 }
1000 gtk_widget_queue_draw(drawing->drawing_area);
1001
1002 /* Update directly when scrolling */
1003 gdk_window_process_updates(drawing->drawing_area->window,
1004 TRUE);
1005
1006 histo_drawing_update_vertical_ruler(drawing);
1007
1008 return 0;
1009}
1010
1011gboolean histo_filter_changed(void * hook_data, void * call_data)
1012{
1013 HistoControlFlowData *histocontrol_flow_data = (HistoControlFlowData*)hook_data;
1014 histoDrawing_t *drawing =histocontrol_flow_data->drawing;
1015
1016 LttvTracesetContext * tsc =
1017 lttvwindow_get_traceset_context(histocontrol_flow_data->tab);
1018
1019 histocontrol_flow_data->histo_main_win_filter =
1020 (LttvFilter*)call_data;
1021 //get_events(event_viewer_data->vadjust_c->value, event_viewer_data);
1022 gtk_widget_set_size_request(
1023 drawing->drawing_area,
1024 -1, -1);
1025 drawing->damage_begin = 0;
1026 drawing->damage_end = drawing->width;
1027
1028 /* //done in, before request!
1029 histo_drawing_clear(drawing,0,drawing->width);
1030 guint i;
1031 for(i=0;i < histocontrol_flow_data->number_of_process->len;i++)
1032 {
1033 g_array_index(histocontrol_flow_data->number_of_process, guint, i) = 0;
1034 }*/
1035
1036 histo_request_event(histocontrol_flow_data,0,drawing->width);
1037
1038 return FALSE;
1039}
1040
1041typedef struct _histo_ClosureData {
1042 EventsRequest *events_request;
1043 LttvTracesetState *tss;
1044 LttTime end_time;
1045 guint x_end;
1046} histo_ClosureData;
1047
1048
1049
1050int histo_before_chunk(void *hook_data, void *call_data)
1051{
1052 EventsRequest *histo_events_request = (EventsRequest*)hook_data;
1053 LttvTracesetState *histo_tss = (LttvTracesetState*)call_data;
1054 HistoControlFlowData *histo_cfd = (HistoControlFlowData*)histo_events_request->viewer_data;
1055#if 0
1056 /* Desactivate sort */
1057 gtk_tree_sortable_set_sort_column_id(
1058 GTK_TREE_SORTABLE(cfd->process_list->list_store),
1059 TRACE_COLUMN,
1060 GTK_SORT_ASCENDING);
1061#endif //0
1062 histo_drawing_chunk_begin(histo_events_request, histo_tss);
1063
1064 return 0;
1065}
1066
1067/*int histo_before_request(void *hook_data, void *call_data)
1068{
1069 EventsRequest *events_request = (EventsRequest*)hook_data;
1070 LttvTracesetState *tss = (LttvTracesetState*)call_data;
1071
1072 histo_drawing_data_request_begin(events_request, tss);
1073
1074 return 0;
1075}
1076*/
1077
1078
1079/*
1080 * after request is necessary in addition of after chunk in order to draw
1081 * lines until the end of the screen. after chunk just draws lines until
1082 * the last event.
1083 *
1084 * for each process
1085 * draw closing line
1086 * expose
1087 */
1088/*int histo_after_request(void *hook_data, void *call_data)
1089{
1090 return 0;
1091}
1092*/
1093/*
1094 * for each process
1095 * draw closing line
1096 * expose
1097 */
1098
1099int histo_after_chunk(void *hook_data, void *call_data)
1100{
1101 EventsRequest *events_request = (EventsRequest*)hook_data;
1102 HistoControlFlowData *histocontrol_flow_data = events_request->viewer_data;
1103 LttvTracesetState *tss = (LttvTracesetState*)call_data;
1104 LttvTracesetContext *tsc = (LttvTracesetContext*)call_data;
1105 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
1106 LttTime end_time;
1107
1108 histoDrawing_t *drawing = histocontrol_flow_data->drawing;
1109
1110 if(tfc != NULL)
1111 end_time = LTT_TIME_MIN(tfc->timestamp, events_request->end_time);
1112 else /* end of traceset, or position now out of request : end */
1113 end_time = events_request->end_time;
1114
1115 guint x, x_end, width;
1116
1117 TimeWindow time_window =
1118 lttvwindow_get_time_window(histocontrol_flow_data->tab);
1119
1120 g_debug("histo after chunk");
1121
1122 histo_convert_time_to_pixels(
1123 time_window,
1124 end_time,
1125 drawing->width,
1126 &x_end);
1127 x = drawing->damage_begin;
1128 width = x_end - x;
1129 drawing->damage_begin = x+width;
1130
1131 histogram_show (histocontrol_flow_data,x,x_end);
1132
1133 return 0;
1134}
1135
This page took 0.063825 seconds and 4 git commands to generate.