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