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