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