1 /*****************************************************************************
2 * Hooks to be called by the main window *
3 *****************************************************************************/
6 #define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
7 #define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
9 //#define PANGO_ENABLE_BACKEND
16 //#include <pango/pango.h>
18 #include <ltt/event.h>
22 #include <lttv/hook.h>
23 #include <lttv/common.h>
24 #include <lttv/state.h>
25 #include <lttv/gtkTraceSet.h>
28 #include "eventhooks.h"
30 #include "processlist.h"
32 #include "cfv-private.h"
35 #define MAX_PATH_LEN 256
39 * Event Viewer's constructor hook
41 * This constructor is given as a parameter to the menuitem and toolbar button
42 * registration. It creates the list.
43 * @param mw A pointer to the parent window.
44 * @return The widget created.
47 h_guicontrolflow(MainWindow
*mw
, LttvTracesetSelector
* s
, char * key
)
49 g_info("h_guicontrolflow, %p, %p, %s", mw
, s
, key
);
50 ControlFlowData
*control_flow_data
= guicontrolflow() ;
52 control_flow_data
->mw
= mw
;
53 TimeWindow
*time_window
= guicontrolflow_get_time_window(control_flow_data
);
54 time_window
->start_time
.tv_sec
= 0;
55 time_window
->start_time
.tv_nsec
= 0;
56 time_window
->time_width
.tv_sec
= 0;
57 time_window
->time_width
.tv_nsec
= 0;
59 LttTime
*current_time
= guicontrolflow_get_current_time(control_flow_data
);
60 current_time
->tv_sec
= 0;
61 current_time
->tv_nsec
= 0;
63 //g_critical("time width1 : %u",time_window->time_width);
70 //g_critical("time width2 : %u",time_window->time_width);
71 // Unreg done in the GuiControlFlow_Destructor
72 reg_update_time_window(update_time_window_hook
, control_flow_data
,
74 reg_update_current_time(update_current_time_hook
, control_flow_data
,
76 return guicontrolflow_get_widget(control_flow_data
) ;
80 int event_selected_hook(void *hook_data
, void *call_data
)
82 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
83 guint
*event_number
= (guint
*) call_data
;
85 g_critical("DEBUG : event selected by main window : %u", *event_number
);
87 // control_flow_data->currently_Selected_Event = *event_number;
88 // control_flow_data->Selected_Event = TRUE ;
90 // tree_v_set_cursor(control_flow_data);
94 /* Hook called before drawing. Gets the initial context at the beginning of the
95 * drawing interval and copy it to the context in event_request.
97 int draw_before_hook(void *hook_data
, void *call_data
)
99 EventRequest
*event_request
= (EventRequest
*)hook_data
;
100 //EventsContext Events_Context = (EventsContext*)call_data;
102 //event_request->Events_Context = Events_Context;
108 * The draw event hook is called by the reading API to have a
109 * particular event drawn on the screen.
110 * @param hook_data ControlFlowData structure of the viewer.
111 * @param call_data Event context.
113 * This function basically draw lines and icons. Two types of lines are drawn :
114 * one small (3 pixels?) representing the state of the process and the second
115 * type is thicker (10 pixels?) representing on which CPU a process is running
116 * (and this only in running state).
118 * Extremums of the lines :
119 * x_min : time of the last event context for this process kept in memory.
120 * x_max : time of the current event.
121 * y : middle of the process in the process list. The process is found in the
122 * list, therefore is it's position in pixels.
124 * The choice of lines'color is defined by the context of the last event for this
127 int draw_event_hook(void *hook_data
, void *call_data
)
129 EventRequest
*event_request
= (EventRequest
*)hook_data
;
130 ControlFlowData
*control_flow_data
= event_request
->control_flow_data
;
132 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
134 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
140 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e
)),"schedchange") == 0)
142 g_critical("schedchange!");
144 /* Add process to process list (if not present) and get drawing "y" from
145 * process position */
146 guint pid_out
, pid_in
;
147 LttvProcessState
*process_out
, *process_in
;
149 guint y_in
= 0, y_out
= 0, height
= 0, pl_height
= 0;
151 ProcessList
*process_list
=
152 guicontrolflow_get_process_list(event_request
->control_flow_data
);
155 LttField
*f
= ltt_event_field(e
);
157 element
= ltt_field_member(f
,0);
158 pid_out
= ltt_event_get_long_unsigned(e
,element
);
159 element
= ltt_field_member(f
,1);
160 pid_in
= ltt_event_get_long_unsigned(e
,element
);
161 g_critical("out : %u in : %u", pid_out
, pid_in
);
164 /* Find process pid_out in the list... */
165 process_out
= lttv_state_find_process(tfs
, pid_out
);
166 g_critical("out : %s",g_quark_to_string(process_out
->state
->s
));
168 birth
= process_out
->creation_time
;
169 gchar
*name
= strdup(g_quark_to_string(process_out
->name
));
170 HashedProcessData
*hashed_process_data_out
= NULL
;
172 if(processlist_get_process_pixels(process_list
,
177 &hashed_process_data_out
) == 1)
179 /* Process not present */
180 processlist_add(process_list
,
185 &hashed_process_data_out
);
186 processlist_get_process_pixels(process_list
,
191 &hashed_process_data_out
);
192 drawing_insert_square( event_request
->control_flow_data
->drawing
, y_out
, height
);
197 /* Find process pid_in in the list... */
198 process_in
= lttv_state_find_process(tfs
, pid_in
);
199 g_critical("in : %s",g_quark_to_string(process_in
->state
->s
));
201 birth
= process_in
->creation_time
;
202 name
= strdup(g_quark_to_string(process_in
->name
));
203 HashedProcessData
*hashed_process_data_in
= NULL
;
205 if(processlist_get_process_pixels(process_list
,
210 &hashed_process_data_in
) == 1)
212 /* Process not present */
213 processlist_add(process_list
,
218 &hashed_process_data_in
);
219 processlist_get_process_pixels(process_list
,
224 &hashed_process_data_in
);
226 drawing_insert_square( event_request
->control_flow_data
->drawing
, y_in
, height
);
231 /* Find pixels corresponding to time of the event. If the time does
232 * not fit in the window, show a warning, not supposed to happend. */
234 guint width
= control_flow_data
->drawing
->drawing_area
->allocation
.width
;
236 LttTime time
= ltt_event_time(e
);
238 LttTime window_end
= ltt_time_add(control_flow_data
->time_window
.time_width
,
239 control_flow_data
->time_window
.start_time
);
242 convert_time_to_pixels(
243 control_flow_data
->time_window
.start_time
,
251 /* draw what represents the event for outgoing process. */
253 DrawContext
*draw_context_out
= hashed_process_data_out
->draw_context
;
254 draw_context_out
->current
->modify_over
->x
= x
;
255 draw_context_out
->current
->modify_over
->y
= y_out
;
256 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
257 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
258 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
259 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
260 draw_context_out
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
261 gdk_gc_copy(draw_context_out
->gc
, widget
->style
->black_gc
);
262 //draw_context_out->gc = widget->style->black_gc;
264 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
265 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
267 GdkColor colorfg_out
= { 0, 0xffff, 0x0000, 0x0000 };
268 GdkColor colorbg_out
= { 0, 0xffff, 0xffff, 0xffff };
269 PropertiesText prop_text_out
;
270 prop_text_out
.foreground
= &colorfg_out
;
271 prop_text_out
.background
= &colorbg_out
;
272 prop_text_out
.size
= 10;
273 prop_text_out
.position
= OVER
;
275 /* Print status of the process : U, WF, WC, E, W, R */
276 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
277 prop_text_out
.text
= "U";
278 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
279 prop_text_out
.text
= "WF";
280 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
281 prop_text_out
.text
= "WC";
282 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
283 prop_text_out
.text
= "E";
284 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
285 prop_text_out
.text
= "W";
286 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
287 prop_text_out
.text
= "R";
289 prop_text_out
.text
= "U";
291 draw_text((void*)&prop_text_out
, (void*)draw_context_out
);
292 gdk_gc_unref(draw_context_out
->gc
);
294 /* Draw the line of the out process */
295 if(draw_context_out
->previous
->middle
->x
== -1)
297 draw_context_out
->previous
->middle
->x
= event_request
->x_begin
;
298 g_critical("out middle x_beg : %u",event_request
->x_begin
);
301 draw_context_out
->current
->middle
->x
= x
;
302 draw_context_out
->current
->middle
->y
= y_out
+ height
/2;
303 draw_context_out
->previous
->middle
->y
= y_out
+ height
/2;
304 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
305 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
306 //draw_context_out->gc = widget->style->black_gc;
307 draw_context_out
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
308 gdk_gc_copy(draw_context_out
->gc
, widget
->style
->black_gc
);
310 PropertiesLine prop_line_out
;
311 prop_line_out
.color
= g_new(GdkColor
,1);
312 prop_line_out
.line_width
= 4;
313 prop_line_out
.style
= GDK_LINE_SOLID
;
314 prop_line_out
.position
= MIDDLE
;
316 /* color of line : status of the process */
317 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
319 prop_line_out
.color
->red
= 0x0000;
320 prop_line_out
.color
->green
= 0x0000;
321 prop_line_out
.color
->blue
= 0x0000;
323 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
325 prop_line_out
.color
->red
= 0x0fff;
326 prop_line_out
.color
->green
= 0x0000;
327 prop_line_out
.color
->blue
= 0x0fff;
329 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
331 prop_line_out
.color
->red
= 0x0fff;
332 prop_line_out
.color
->green
= 0x0fff;
333 prop_line_out
.color
->blue
= 0x0000;
335 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
337 prop_line_out
.color
->red
= 0xffff;
338 prop_line_out
.color
->green
= 0x0000;
339 prop_line_out
.color
->blue
= 0xffff;
341 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
343 prop_line_out
.color
->red
= 0xffff;
344 prop_line_out
.color
->green
= 0x0000;
345 prop_line_out
.color
->blue
= 0x0000;
347 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
349 prop_line_out
.color
->red
= 0x0000;
350 prop_line_out
.color
->green
= 0xffff;
351 prop_line_out
.color
->blue
= 0x0000;
355 prop_line_out
.color
->red
= 0x0000;
356 prop_line_out
.color
->green
= 0x0000;
357 prop_line_out
.color
->blue
= 0x0000;
360 draw_line((void*)&prop_line_out
, (void*)draw_context_out
);
361 g_free(prop_line_out
.color
);
362 gdk_gc_unref(draw_context_out
->gc
);
363 /* Note : finishing line will have to be added when trace read over. */
365 /* Finally, update the drawing context of the pid_in. */
367 DrawContext
*draw_context_in
= hashed_process_data_in
->draw_context
;
368 draw_context_in
->current
->modify_over
->x
= x
;
369 draw_context_in
->current
->modify_over
->y
= y_in
;
370 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
371 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
372 widget
= control_flow_data
->drawing
->drawing_area
;
373 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
374 //draw_context_in->gc = widget->style->black_gc;
375 draw_context_in
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
376 gdk_gc_copy(draw_context_in
->gc
, widget
->style
->black_gc
);
378 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
379 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
381 GdkColor colorfg_in
= { 0, 0x0000, 0xffff, 0x0000 };
382 GdkColor colorbg_in
= { 0, 0xffff, 0xffff, 0xffff };
383 PropertiesText prop_text_in
;
384 prop_text_in
.foreground
= &colorfg_in
;
385 prop_text_in
.background
= &colorbg_in
;
386 prop_text_in
.size
= 10;
387 prop_text_in
.position
= OVER
;
389 /* Print status of the process : U, WF, WC, E, W, R */
390 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
391 prop_text_in
.text
= "U";
392 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
393 prop_text_in
.text
= "WF";
394 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
395 prop_text_in
.text
= "WC";
396 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
397 prop_text_in
.text
= "E";
398 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
399 prop_text_in
.text
= "W";
400 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
401 prop_text_in
.text
= "R";
403 prop_text_in
.text
= "U";
405 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
406 gdk_gc_unref(draw_context_in
->gc
);
408 /* Draw the line of the in process */
409 if(draw_context_in
->previous
->middle
->x
== -1)
411 draw_context_in
->previous
->middle
->x
= event_request
->x_begin
;
412 g_critical("in middle x_beg : %u",event_request
->x_begin
);
415 draw_context_in
->current
->middle
->x
= x
;
416 draw_context_in
->previous
->middle
->y
= y_in
+ height
/2;
417 draw_context_in
->current
->middle
->y
= y_in
+ height
/2;
418 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
419 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
420 //draw_context_in->gc = widget->style->black_gc;
421 draw_context_in
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
422 gdk_gc_copy(draw_context_in
->gc
, widget
->style
->black_gc
);
424 PropertiesLine prop_line_in
;
425 prop_line_in
.color
= g_new(GdkColor
,1);
426 prop_line_in
.line_width
= 4;
427 prop_line_in
.style
= GDK_LINE_SOLID
;
428 prop_line_in
.position
= MIDDLE
;
430 /* color of line : status of the process */
431 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
433 prop_line_in
.color
->red
= 0x0000;
434 prop_line_in
.color
->green
= 0x0000;
435 prop_line_in
.color
->blue
= 0x0000;
437 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
439 prop_line_in
.color
->red
= 0x0fff;
440 prop_line_in
.color
->green
= 0x0000;
441 prop_line_in
.color
->blue
= 0x0fff;
443 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
445 prop_line_in
.color
->red
= 0x0fff;
446 prop_line_in
.color
->green
= 0x0fff;
447 prop_line_in
.color
->blue
= 0x0000;
449 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
451 prop_line_in
.color
->red
= 0xffff;
452 prop_line_in
.color
->green
= 0x0000;
453 prop_line_in
.color
->blue
= 0xffff;
455 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
457 prop_line_in
.color
->red
= 0xffff;
458 prop_line_in
.color
->green
= 0x0000;
459 prop_line_in
.color
->blue
= 0x0000;
461 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
463 prop_line_in
.color
->red
= 0x0000;
464 prop_line_in
.color
->green
= 0xffff;
465 prop_line_in
.color
->blue
= 0x0000;
469 prop_line_in
.color
->red
= 0x0000;
470 prop_line_in
.color
->green
= 0x0000;
471 prop_line_in
.color
->blue
= 0x0000;
474 draw_line((void*)&prop_line_in
, (void*)draw_context_in
);
475 g_free(prop_line_in
.color
);
476 gdk_gc_unref(draw_context_in
->gc
);
483 GString
*string
= g_string_new("");;
484 gboolean field_names
= TRUE
, state
= TRUE
;
486 lttv_event_to_string(e
, tfc
->tf
, string
, TRUE
, field_names
, tfs
);
487 g_string_append_printf(string
,"\n");
490 g_string_append_printf(string
, " %s",
491 g_quark_to_string(tfs
->process
->state
->s
));
494 g_info("%s",string
->str
);
496 g_string_free(string
, TRUE
);
498 /* End of text dump */
504 int draw_after_hook(void *hook_data
, void *call_data
)
506 EventRequest
*event_request
= (EventRequest
*)hook_data
;
507 ControlFlowData
*control_flow_data
= event_request
->control_flow_data
;
509 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
511 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
517 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e
)),"schedchange") == 0)
519 g_critical("schedchange!");
521 /* Add process to process list (if not present) and get drawing "y" from
522 * process position */
523 guint pid_out
, pid_in
;
524 LttvProcessState
*process_out
, *process_in
;
526 guint y_in
= 0, y_out
= 0, height
= 0, pl_height
= 0;
528 ProcessList
*process_list
=
529 guicontrolflow_get_process_list(event_request
->control_flow_data
);
532 LttField
*f
= ltt_event_field(e
);
534 element
= ltt_field_member(f
,0);
535 pid_out
= ltt_event_get_long_unsigned(e
,element
);
536 element
= ltt_field_member(f
,1);
537 pid_in
= ltt_event_get_long_unsigned(e
,element
);
538 g_critical("out : %u in : %u", pid_out
, pid_in
);
541 /* Find process pid_out in the list... */
542 process_out
= lttv_state_find_process(tfs
, pid_out
);
543 g_critical("out : %s",g_quark_to_string(process_out
->state
->s
));
545 birth
= process_out
->creation_time
;
546 gchar
*name
= strdup(g_quark_to_string(process_out
->name
));
547 HashedProcessData
*hashed_process_data_out
= NULL
;
549 if(processlist_get_process_pixels(process_list
,
554 &hashed_process_data_out
) == 1)
556 /* Process not present */
557 processlist_add(process_list
,
562 &hashed_process_data_out
);
563 processlist_get_process_pixels(process_list
,
568 &hashed_process_data_out
);
569 drawing_insert_square( event_request
->control_flow_data
->drawing
, y_out
, height
);
574 /* Find process pid_in in the list... */
575 process_in
= lttv_state_find_process(tfs
, pid_in
);
576 g_critical("in : %s",g_quark_to_string(process_in
->state
->s
));
578 birth
= process_in
->creation_time
;
579 name
= strdup(g_quark_to_string(process_in
->name
));
580 HashedProcessData
*hashed_process_data_in
= NULL
;
582 if(processlist_get_process_pixels(process_list
,
587 &hashed_process_data_in
) == 1)
589 /* Process not present */
590 processlist_add(process_list
,
595 &hashed_process_data_in
);
596 processlist_get_process_pixels(process_list
,
601 &hashed_process_data_in
);
603 drawing_insert_square( event_request
->control_flow_data
->drawing
, y_in
, height
);
608 /* Find pixels corresponding to time of the event. If the time does
609 * not fit in the window, show a warning, not supposed to happend. */
611 //guint width = control_flow_data->drawing->drawing_area->allocation.width;
613 //LttTime time = ltt_event_time(e);
615 //LttTime window_end = ltt_time_add(control_flow_data->time_window.time_width,
616 // control_flow_data->time_window.start_time);
619 //convert_time_to_pixels(
620 // control_flow_data->time_window.start_time,
626 //assert(x <= width);
628 /* draw what represents the event for outgoing process. */
630 DrawContext
*draw_context_out
= hashed_process_data_out
->draw_context
;
631 //draw_context_out->current->modify_over->x = x;
632 draw_context_out
->current
->modify_over
->y
= y_out
;
633 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
634 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
635 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
636 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
637 draw_context_out
->gc
= widget
->style
->black_gc
;
639 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
640 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
642 GdkColor colorfg_out
= { 0, 0xffff, 0x0000, 0x0000 };
643 GdkColor colorbg_out
= { 0, 0xffff, 0xffff, 0xffff };
644 PropertiesText prop_text_out
;
645 prop_text_out
.foreground
= &colorfg_out
;
646 prop_text_out
.background
= &colorbg_out
;
647 prop_text_out
.size
= 10;
648 prop_text_out
.position
= OVER
;
650 /* Print status of the process : U, WF, WC, E, W, R */
651 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
652 prop_text_out
.text
= "U";
653 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
654 prop_text_out
.text
= "WF";
655 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
656 prop_text_out
.text
= "WC";
657 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
658 prop_text_out
.text
= "E";
659 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
660 prop_text_out
.text
= "W";
661 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
662 prop_text_out
.text
= "R";
664 prop_text_out
.text
= "U";
666 draw_text((void*)&prop_text_out
, (void*)draw_context_out
);
668 draw_context_out
->current
->middle
->y
= y_out
+height
/2;
669 draw_context_out
->current
->status
= process_out
->state
->s
;
671 /* for pid_out : remove previous, Prev = current, new current (default) */
672 g_free(draw_context_out
->previous
->modify_under
);
673 g_free(draw_context_out
->previous
->modify_middle
);
674 g_free(draw_context_out
->previous
->modify_over
);
675 g_free(draw_context_out
->previous
->under
);
676 g_free(draw_context_out
->previous
->middle
);
677 g_free(draw_context_out
->previous
->over
);
678 g_free(draw_context_out
->previous
);
680 draw_context_out
->previous
= draw_context_out
->current
;
682 draw_context_out
->current
= g_new(DrawInfo
,1);
683 draw_context_out
->current
->over
= g_new(ItemInfo
,1);
684 draw_context_out
->current
->over
->x
= -1;
685 draw_context_out
->current
->over
->y
= -1;
686 draw_context_out
->current
->middle
= g_new(ItemInfo
,1);
687 draw_context_out
->current
->middle
->x
= -1;
688 draw_context_out
->current
->middle
->y
= -1;
689 draw_context_out
->current
->under
= g_new(ItemInfo
,1);
690 draw_context_out
->current
->under
->x
= -1;
691 draw_context_out
->current
->under
->y
= -1;
692 draw_context_out
->current
->modify_over
= g_new(ItemInfo
,1);
693 draw_context_out
->current
->modify_over
->x
= -1;
694 draw_context_out
->current
->modify_over
->y
= -1;
695 draw_context_out
->current
->modify_middle
= g_new(ItemInfo
,1);
696 draw_context_out
->current
->modify_middle
->x
= -1;
697 draw_context_out
->current
->modify_middle
->y
= -1;
698 draw_context_out
->current
->modify_under
= g_new(ItemInfo
,1);
699 draw_context_out
->current
->modify_under
->x
= -1;
700 draw_context_out
->current
->modify_under
->y
= -1;
701 draw_context_out
->current
->status
= LTTV_STATE_UNNAMED
;
703 /* Finally, update the drawing context of the pid_in. */
705 DrawContext
*draw_context_in
= hashed_process_data_in
->draw_context
;
706 //draw_context_in->current->modify_over->x = x;
707 draw_context_in
->current
->modify_over
->y
= y_in
;
708 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
709 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
710 widget
= control_flow_data
->drawing
->drawing_area
;
711 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
712 draw_context_in
->gc
= widget
->style
->black_gc
;
714 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
715 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
717 GdkColor colorfg_in
= { 0, 0x0000, 0xffff, 0x0000 };
718 GdkColor colorbg_in
= { 0, 0xffff, 0xffff, 0xffff };
719 PropertiesText prop_text_in
;
720 prop_text_in
.foreground
= &colorfg_in
;
721 prop_text_in
.background
= &colorbg_in
;
722 prop_text_in
.size
= 10;
723 prop_text_in
.position
= OVER
;
725 /* Print status of the process : U, WF, WC, E, W, R */
726 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
727 prop_text_in
.text
= "U";
728 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
729 prop_text_in
.text
= "WF";
730 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
731 prop_text_in
.text
= "WC";
732 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
733 prop_text_in
.text
= "E";
734 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
735 prop_text_in
.text
= "W";
736 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
737 prop_text_in
.text
= "R";
739 prop_text_in
.text
= "U";
741 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
743 draw_context_in
->current
->middle
->y
= y_in
+height
/2;
744 draw_context_in
->current
->status
= process_in
->state
->s
;
746 /* for pid_in : remove previous, Prev = current, new current (default) */
747 g_free(draw_context_in
->previous
->modify_under
);
748 g_free(draw_context_in
->previous
->modify_middle
);
749 g_free(draw_context_in
->previous
->modify_over
);
750 g_free(draw_context_in
->previous
->under
);
751 g_free(draw_context_in
->previous
->middle
);
752 g_free(draw_context_in
->previous
->over
);
753 g_free(draw_context_in
->previous
);
755 draw_context_in
->previous
= draw_context_in
->current
;
757 draw_context_in
->current
= g_new(DrawInfo
,1);
758 draw_context_in
->current
->over
= g_new(ItemInfo
,1);
759 draw_context_in
->current
->over
->x
= -1;
760 draw_context_in
->current
->over
->y
= -1;
761 draw_context_in
->current
->middle
= g_new(ItemInfo
,1);
762 draw_context_in
->current
->middle
->x
= -1;
763 draw_context_in
->current
->middle
->y
= -1;
764 draw_context_in
->current
->under
= g_new(ItemInfo
,1);
765 draw_context_in
->current
->under
->x
= -1;
766 draw_context_in
->current
->under
->y
= -1;
767 draw_context_in
->current
->modify_over
= g_new(ItemInfo
,1);
768 draw_context_in
->current
->modify_over
->x
= -1;
769 draw_context_in
->current
->modify_over
->y
= -1;
770 draw_context_in
->current
->modify_middle
= g_new(ItemInfo
,1);
771 draw_context_in
->current
->modify_middle
->x
= -1;
772 draw_context_in
->current
->modify_middle
->y
= -1;
773 draw_context_in
->current
->modify_under
= g_new(ItemInfo
,1);
774 draw_context_in
->current
->modify_under
->x
= -1;
775 draw_context_in
->current
->modify_under
->y
= -1;
776 draw_context_in
->current
->status
= LTTV_STATE_UNNAMED
;
786 gint
update_time_window_hook(void *hook_data
, void *call_data
)
788 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
789 TimeWindow
*old_time_window
=
790 guicontrolflow_get_time_window(control_flow_data
);
791 TimeWindow
*new_time_window
= ((TimeWindow
*)call_data
);
793 /* Two cases : zoom in/out or scrolling */
795 /* In order to make sure we can reuse the old drawing, the scale must
796 * be the same and the new time interval being partly located in the
797 * currently shown time interval. (reuse is only for scrolling)
800 g_info("Old time window HOOK : %u, %u to %u, %u",
801 old_time_window
->start_time
.tv_sec
,
802 old_time_window
->start_time
.tv_nsec
,
803 old_time_window
->time_width
.tv_sec
,
804 old_time_window
->time_width
.tv_nsec
);
806 g_info("New time window HOOK : %u, %u to %u, %u",
807 new_time_window
->start_time
.tv_sec
,
808 new_time_window
->start_time
.tv_nsec
,
809 new_time_window
->time_width
.tv_sec
,
810 new_time_window
->time_width
.tv_nsec
);
812 if( new_time_window
->time_width
.tv_sec
== old_time_window
->time_width
.tv_sec
813 && new_time_window
->time_width
.tv_nsec
== old_time_window
->time_width
.tv_nsec
)
815 /* Same scale (scrolling) */
817 LttTime
*ns
= &new_time_window
->start_time
;
818 LttTime
*os
= &old_time_window
->start_time
;
819 LttTime old_end
= ltt_time_add(old_time_window
->start_time
,
820 old_time_window
->time_width
);
821 LttTime new_end
= ltt_time_add(new_time_window
->start_time
,
822 new_time_window
->time_width
);
824 //if(ns<os+w && os+w<ns+w)
825 //if(ns<old_end && os<ns)
826 if(ltt_time_compare(*ns
, old_end
) == -1
827 && ltt_time_compare(*os
, *ns
) == -1)
829 g_info("scrolling near right");
830 /* Scroll right, keep right part of the screen */
832 guint width
= control_flow_data
->drawing
->drawing_area
->allocation
.width
;
833 convert_time_to_pixels(
840 /* Copy old data to new location */
841 gdk_draw_drawable (control_flow_data
->drawing
->pixmap
,
842 control_flow_data
->drawing
->drawing_area
->style
->white_gc
,
843 control_flow_data
->drawing
->pixmap
,
848 convert_time_to_pixels(
855 *old_time_window
= *new_time_window
;
856 /* Clear the data request background, but not SAFETY */
857 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
858 control_flow_data
->drawing
->drawing_area
->style
->white_gc
,
861 control_flow_data
->drawing
->width
- x
, // do not overlap
862 control_flow_data
->drawing
->height
+SAFETY
);
863 /* Get new data for the rest. */
864 drawing_data_request(control_flow_data
->drawing
,
865 &control_flow_data
->drawing
->pixmap
,
867 control_flow_data
->drawing
->width
- x
,
868 control_flow_data
->drawing
->height
);
870 drawing_refresh(control_flow_data
->drawing
,
872 control_flow_data
->drawing
->width
,
873 control_flow_data
->drawing
->height
);
878 //if(ns<os && os<ns+w)
879 //if(ns<os && os<new_end)
880 if(ltt_time_compare(*ns
,*os
) == -1
881 && ltt_time_compare(*os
,new_end
) == -1)
883 g_info("scrolling near left");
884 /* Scroll left, keep left part of the screen */
886 guint width
= control_flow_data
->drawing
->drawing_area
->allocation
.width
;
887 convert_time_to_pixels(
894 /* Copy old data to new location */
895 gdk_draw_drawable (control_flow_data
->drawing
->pixmap
,
896 control_flow_data
->drawing
->drawing_area
->style
->white_gc
,
897 control_flow_data
->drawing
->pixmap
,
902 *old_time_window
= *new_time_window
;
904 /* Clean the data request background */
905 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
906 control_flow_data
->drawing
->drawing_area
->style
->white_gc
,
910 control_flow_data
->drawing
->height
+SAFETY
);
911 /* Get new data for the rest. */
912 drawing_data_request(control_flow_data
->drawing
,
913 &control_flow_data
->drawing
->pixmap
,
916 control_flow_data
->drawing
->height
);
918 drawing_refresh(control_flow_data
->drawing
,
920 control_flow_data
->drawing
->width
,
921 control_flow_data
->drawing
->height
);
924 g_info("scrolling far");
925 /* Cannot reuse any part of the screen : far jump */
926 *old_time_window
= *new_time_window
;
929 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
930 control_flow_data
->drawing
->drawing_area
->style
->white_gc
,
933 control_flow_data
->drawing
->width
+SAFETY
, // do not overlap
934 control_flow_data
->drawing
->height
+SAFETY
);
936 drawing_data_request(control_flow_data
->drawing
,
937 &control_flow_data
->drawing
->pixmap
,
939 control_flow_data
->drawing
->width
,
940 control_flow_data
->drawing
->height
);
942 drawing_refresh(control_flow_data
->drawing
,
944 control_flow_data
->drawing
->width
,
945 control_flow_data
->drawing
->height
);
949 /* Different scale (zoom) */
952 *old_time_window
= *new_time_window
;
954 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
955 control_flow_data
->drawing
->drawing_area
->style
->white_gc
,
958 control_flow_data
->drawing
->width
+SAFETY
, // do not overlap
959 control_flow_data
->drawing
->height
+SAFETY
);
962 drawing_data_request(control_flow_data
->drawing
,
963 &control_flow_data
->drawing
->pixmap
,
965 control_flow_data
->drawing
->width
,
966 control_flow_data
->drawing
->height
);
968 drawing_refresh(control_flow_data
->drawing
,
970 control_flow_data
->drawing
->width
,
971 control_flow_data
->drawing
->height
);
977 gint
update_current_time_hook(void *hook_data
, void *call_data
)
979 ControlFlowData
*control_flow_data
= (ControlFlowData
*)hook_data
;
981 LttTime
* current_time
=
982 guicontrolflow_get_current_time(control_flow_data
);
983 *current_time
= *((LttTime
*)call_data
);
985 TimeWindow time_window
;
987 LttTime time_begin
= control_flow_data
->time_window
.start_time
;
988 LttTime width
= control_flow_data
->time_window
.time_width
;
989 LttTime half_width
= ltt_time_div(width
,2.0);
990 LttTime time_end
= ltt_time_add(time_begin
, width
);
992 LttvTracesetContext
* tsc
=
993 get_traceset_context(control_flow_data
->mw
);
995 LttTime trace_start
= tsc
->Time_Span
->startTime
;
996 LttTime trace_end
= tsc
->Time_Span
->endTime
;
998 g_info("New current time HOOK : %u, %u", current_time
->tv_sec
,
999 current_time
->tv_nsec
);
1003 /* If current time is inside time interval, just move the highlight
1006 /* Else, we have to change the time interval. We have to tell it
1007 * to the main window. */
1008 /* The time interval change will take care of placing the current
1009 * time at the center of the visible area, or nearest possible if we are
1010 * at one end of the trace. */
1013 if(ltt_time_compare(*current_time
, time_begin
) == -1)
1015 if(ltt_time_compare(*current_time
,
1016 ltt_time_add(trace_start
,half_width
)) == -1)
1017 time_begin
= trace_start
;
1019 time_begin
= ltt_time_sub(*current_time
,half_width
);
1021 time_window
.start_time
= time_begin
;
1022 time_window
.time_width
= width
;
1024 set_time_window(control_flow_data
->mw
, &time_window
);
1026 else if(ltt_time_compare(*current_time
, time_end
) == 1)
1028 if(ltt_time_compare(*current_time
, ltt_time_sub(trace_end
, half_width
)) == 1)
1029 time_begin
= ltt_time_sub(trace_end
,width
);
1031 time_begin
= ltt_time_sub(*current_time
,half_width
);
1033 time_window
.start_time
= time_begin
;
1034 time_window
.time_width
= width
;
1036 set_time_window(control_flow_data
->mw
, &time_window
);
1039 gtk_widget_queue_draw(control_flow_data
->drawing
->drawing_area
);
1044 typedef struct _ClosureData
{
1045 EventRequest
*event_request
;
1050 void draw_closure(gpointer key
, gpointer value
, gpointer user_data
)
1052 ProcessInfo
*process_info
= (ProcessInfo
*)key
;
1053 HashedProcessData
*hashed_process_data
= (HashedProcessData
*)value
;
1054 ClosureData
*closure_data
= (ClosureData
*)user_data
;
1056 ControlFlowData
*control_flow_data
=
1057 closure_data
->event_request
->control_flow_data
;
1059 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
1061 /* Get y position of process */
1064 processlist_get_pixels_from_data( control_flow_data
->process_list
,
1066 hashed_process_data
,
1069 /* Get last state of process */
1070 LttvTraceContext
*tc
=
1071 (LttvTraceContext
*)closure_data
->ts
;
1073 LttvTraceState
*ts
= closure_data
->ts
;
1074 LttvProcessState
*process
;
1076 process
= lttv_state_find_process((LttvTracefileState
*)ts
, process_info
->pid
);
1078 /* Draw the closing line */
1079 DrawContext
*draw_context
= hashed_process_data
->draw_context
;
1080 if(draw_context
->previous
->middle
->x
== -1)
1082 draw_context
->previous
->middle
->x
= closure_data
->event_request
->x_begin
;
1083 g_critical("out middle x_beg : %u",closure_data
->event_request
->x_begin
);
1086 draw_context
->current
->middle
->x
= closure_data
->event_request
->x_end
;
1087 draw_context
->current
->middle
->y
= y
+ height
/2;
1088 draw_context
->previous
->middle
->y
= y
+ height
/2;
1089 draw_context
->drawable
= control_flow_data
->drawing
->pixmap
;
1090 draw_context
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
1091 //draw_context->gc = widget->style->black_gc;
1092 draw_context
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
1093 gdk_gc_copy(draw_context
->gc
, widget
->style
->black_gc
);
1095 PropertiesLine prop_line
;
1096 prop_line
.color
= g_new(GdkColor
,1);
1097 prop_line
.line_width
= 6;
1098 prop_line
.style
= GDK_LINE_SOLID
;
1099 prop_line
.position
= MIDDLE
;
1101 /* color of line : status of the process */
1102 if(process
->state
->s
== LTTV_STATE_UNNAMED
)
1104 prop_line
.color
->red
= 0x0000;
1105 prop_line
.color
->green
= 0x0000;
1106 prop_line
.color
->blue
= 0x0000;
1108 else if(process
->state
->s
== LTTV_STATE_WAIT_FORK
)
1110 prop_line
.color
->red
= 0x0fff;
1111 prop_line
.color
->green
= 0x0000;
1112 prop_line
.color
->blue
= 0x0fff;
1114 else if(process
->state
->s
== LTTV_STATE_WAIT_CPU
)
1116 prop_line
.color
->red
= 0x0fff;
1117 prop_line
.color
->green
= 0x0fff;
1118 prop_line
.color
->blue
= 0x0000;
1120 else if(process
->state
->s
== LTTV_STATE_EXIT
)
1122 prop_line
.color
->red
= 0xffff;
1123 prop_line
.color
->green
= 0x0000;
1124 prop_line
.color
->blue
= 0xffff;
1126 else if(process
->state
->s
== LTTV_STATE_WAIT
)
1128 prop_line
.color
->red
= 0xffff;
1129 prop_line
.color
->green
= 0x0000;
1130 prop_line
.color
->blue
= 0x0000;
1132 else if(process
->state
->s
== LTTV_STATE_RUN
)
1134 prop_line
.color
->red
= 0x0000;
1135 prop_line
.color
->green
= 0xffff;
1136 prop_line
.color
->blue
= 0x0000;
1140 prop_line
.color
->red
= 0x0000;
1141 prop_line
.color
->green
= 0x0000;
1142 prop_line
.color
->blue
= 0x0000;
1145 draw_line((void*)&prop_line
, (void*)draw_context
);
1146 g_free(prop_line
.color
);
1147 gdk_gc_unref(draw_context
->gc
);
1149 /* Reset draw_context of the process for next request */
1151 hashed_process_data
->draw_context
->drawable
= NULL
;
1152 hashed_process_data
->draw_context
->gc
= NULL
;
1153 hashed_process_data
->draw_context
->pango_layout
= NULL
;
1154 hashed_process_data
->draw_context
->current
->over
->x
= -1;
1155 hashed_process_data
->draw_context
->current
->over
->y
= -1;
1156 hashed_process_data
->draw_context
->current
->middle
->x
= -1;
1157 hashed_process_data
->draw_context
->current
->middle
->y
= -1;
1158 hashed_process_data
->draw_context
->current
->under
->x
= -1;
1159 hashed_process_data
->draw_context
->current
->under
->y
= -1;
1160 hashed_process_data
->draw_context
->current
->modify_over
->x
= -1;
1161 hashed_process_data
->draw_context
->current
->modify_over
->y
= -1;
1162 hashed_process_data
->draw_context
->current
->modify_middle
->x
= -1;
1163 hashed_process_data
->draw_context
->current
->modify_middle
->y
= -1;
1164 hashed_process_data
->draw_context
->current
->modify_under
->x
= -1;
1165 hashed_process_data
->draw_context
->current
->modify_under
->y
= -1;
1166 hashed_process_data
->draw_context
->current
->status
= LTTV_STATE_UNNAMED
;
1167 hashed_process_data
->draw_context
->previous
->over
->x
= -1;
1168 hashed_process_data
->draw_context
->previous
->over
->y
= -1;
1169 hashed_process_data
->draw_context
->previous
->middle
->x
= -1;
1170 hashed_process_data
->draw_context
->previous
->middle
->y
= -1;
1171 hashed_process_data
->draw_context
->previous
->under
->x
= -1;
1172 hashed_process_data
->draw_context
->previous
->under
->y
= -1;
1173 hashed_process_data
->draw_context
->previous
->modify_over
->x
= -1;
1174 hashed_process_data
->draw_context
->previous
->modify_over
->y
= -1;
1175 hashed_process_data
->draw_context
->previous
->modify_middle
->x
= -1;
1176 hashed_process_data
->draw_context
->previous
->modify_middle
->y
= -1;
1177 hashed_process_data
->draw_context
->previous
->modify_under
->x
= -1;
1178 hashed_process_data
->draw_context
->previous
->modify_under
->y
= -1;
1179 hashed_process_data
->draw_context
->previous
->status
= LTTV_STATE_UNNAMED
;
1187 * new default prev and current
1189 int after_data_request(void *hook_data
, void *call_data
)
1191 EventRequest
*event_request
= (EventRequest
*)hook_data
;
1192 ControlFlowData
*control_flow_data
= event_request
->control_flow_data
;
1194 ProcessList
*process_list
=
1195 guicontrolflow_get_process_list(event_request
->control_flow_data
);
1197 ClosureData closure_data
;
1198 closure_data
.event_request
= (EventRequest
*)hook_data
;
1199 closure_data
.ts
= (LttvTraceState
*)call_data
;
1201 g_hash_table_foreach(process_list
->process_hash
, draw_closure
,
1202 (void*)&closure_data
);