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