1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Mathieu Desnoyers
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;
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.
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,
20 /*****************************************************************************
21 * Hooks to be called by the main window *
22 *****************************************************************************/
25 //#define PANGO_ENABLE_BACKEND
33 //#include <pango/pango.h>
35 #include <ltt/event.h>
39 #include <lttv/lttv.h>
40 #include <lttv/hook.h>
41 #include <lttv/state.h>
42 #include <lttvwindow/lttvwindow.h>
43 #include <lttvwindow/lttvwindowtraces.h>
46 #include "eventhooks.h"
48 #include "processlist.h"
50 #include "cfv-private.h"
53 #define MAX_PATH_LEN 256
56 /* Action to do when background computation completed.
58 * Eventually, will have to check that every requested traces are finished
59 * before doing the redraw.
62 gint
background_ready(void *hook_data
, void *call_data
)
64 ControlFlowData
*control_flow_data
= (ControlFlowData
*)hook_data
;
65 LttvTrace
*trace
= (LttvTrace
*)call_data
;
67 g_debug("control flow viewer : background computation data ready.");
69 redraw_notify(control_flow_data
, NULL
);
75 /* Request background computation. Verify if it is in progress or ready first.
77 * Right now, for all loaded traces.
79 * Later : must be only for each trace in the tab's traceset.
81 void request_background_data(ControlFlowData
*control_flow_data
)
83 gint num_traces
= lttvwindowtraces_get_number();
87 LttvHooks
*background_ready_hook
=
89 lttv_hooks_add(background_ready_hook
, background_ready
, control_flow_data
,
92 for(i
=0;i
<num_traces
;i
++) {
93 trace
= lttvwindowtraces_get_trace(i
);
95 if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace
)==FALSE
) {
97 if(lttvwindowtraces_get_in_progress(g_quark_from_string("state"),
99 /* We first remove requests that could have been done for the same
100 * information. Happens when two viewers ask for it before servicing
103 lttvwindowtraces_background_request_remove(trace
, "state");
104 lttvwindowtraces_background_request_queue(trace
,
106 lttvwindowtraces_background_notify_queue(control_flow_data
,
110 background_ready_hook
);
111 } else { /* in progress */
113 lttvwindowtraces_background_notify_current(control_flow_data
,
117 background_ready_hook
);
123 lttv_hooks_destroy(background_ready_hook
);
130 * Event Viewer's constructor hook
132 * This constructor is given as a parameter to the menuitem and toolbar button
133 * registration. It creates the list.
134 * @param tab A pointer to the parent tab.
135 * @return The widget created.
138 h_guicontrolflow(Tab
*tab
, LttvTracesetSelector
* s
, char * key
)
140 g_info("h_guicontrolflow, %p, %p, %s", tab
, s
, key
);
141 ControlFlowData
*control_flow_data
= guicontrolflow() ;
143 control_flow_data
->tab
= tab
;
145 //g_debug("time width2 : %u",time_window->time_width);
146 // Unreg done in the GuiControlFlow_Destructor
147 lttvwindow_register_traceset_notify(tab
,
151 lttvwindow_register_time_window_notify(tab
,
152 update_time_window_hook
,
154 lttvwindow_register_current_time_notify(tab
,
155 update_current_time_hook
,
157 lttvwindow_register_redraw_notify(tab
,
160 lttvwindow_register_continue_notify(tab
,
163 request_background_data(control_flow_data
);
166 return guicontrolflow_get_widget(control_flow_data
) ;
170 int event_selected_hook(void *hook_data
, void *call_data
)
172 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
173 guint
*event_number
= (guint
*) call_data
;
175 g_debug("DEBUG : event selected by main window : %u", *event_number
);
177 // control_flow_data->currently_Selected_Event = *event_number;
178 // control_flow_data->Selected_Event = TRUE ;
180 // tree_v_set_cursor(control_flow_data);
184 /* Hook called before drawing. Gets the initial context at the beginning of the
185 * drawing interval and copy it to the context in event_request.
187 int draw_before_hook(void *hook_data
, void *call_data
)
189 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
190 //EventsContext Events_Context = (EventsContext*)call_data;
192 //event_request->Events_Context = Events_Context;
198 * The draw event hook is called by the reading API to have a
199 * particular event drawn on the screen.
200 * @param hook_data ControlFlowData structure of the viewer.
201 * @param call_data Event context.
203 * This function basically draw lines and icons. Two types of lines are drawn :
204 * one small (3 pixels?) representing the state of the process and the second
205 * type is thicker (10 pixels?) representing on which CPU a process is running
206 * (and this only in running state).
208 * Extremums of the lines :
209 * x_min : time of the last event context for this process kept in memory.
210 * x_max : time of the current event.
211 * y : middle of the process in the process list. The process is found in the
212 * list, therefore is it's position in pixels.
214 * The choice of lines'color is defined by the context of the last event for this
217 int draw_event_hook(void *hook_data
, void *call_data
)
219 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
220 ControlFlowData
*control_flow_data
=
221 (ControlFlowData
*)events_request
->viewer_data
;
222 Tab
*tab
= control_flow_data
->tab
;
224 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
226 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
227 LttvTraceState
*ts
=(LttvTraceState
*)LTTV_TRACEFILE_CONTEXT(tfs
)->t_context
;
232 LttTime evtime
= ltt_event_time(e
);
233 TimeWindow time_window
=
234 lttvwindow_get_time_window(tab
);
236 LttTime end_time
= ltt_time_add(time_window
.start_time
,
237 time_window
.time_width
);
238 //if(time < time_beg || time > time_end) return;
239 if(ltt_time_compare(evtime
, time_window
.start_time
) == -1
240 || ltt_time_compare(evtime
, end_time
) == 1)
243 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e
)),"schedchange") == 0)
245 g_debug("schedchange!");
247 /* Add process to process list (if not present) and get drawing "y" from
248 * process position */
249 guint pid_out
, pid_in
;
250 LttvProcessState
*process_out
, *process_in
;
252 guint y_in
= 0, y_out
= 0, height
= 0, pl_height
= 0;
254 ProcessList
*process_list
=
255 guicontrolflow_get_process_list(control_flow_data
);
258 LttField
*f
= ltt_event_field(e
);
260 element
= ltt_field_member(f
,0);
261 pid_out
= ltt_event_get_long_unsigned(e
,element
);
262 element
= ltt_field_member(f
,1);
263 pid_in
= ltt_event_get_long_unsigned(e
,element
);
264 g_debug("out : %u in : %u", pid_out
, pid_in
);
267 /* Find process pid_out in the list... */
268 process_out
= lttv_state_find_process(tfs
, pid_out
);
269 if(process_out
== NULL
) return 0;
270 g_debug("out : %s",g_quark_to_string(process_out
->state
->s
));
272 birth
= process_out
->creation_time
;
273 gchar
*name
= strdup(g_quark_to_string(process_out
->name
));
274 HashedProcessData
*hashed_process_data_out
= NULL
;
276 if(processlist_get_process_pixels(process_list
,
279 tfc
->t_context
->index
,
282 &hashed_process_data_out
) == 1)
284 /* Process not present */
285 processlist_add(process_list
,
288 tfc
->t_context
->index
,
291 &hashed_process_data_out
);
292 processlist_get_process_pixels(process_list
,
295 tfc
->t_context
->index
,
298 &hashed_process_data_out
);
299 drawing_insert_square( control_flow_data
->drawing
, y_out
, height
);
304 /* Find process pid_in in the list... */
305 process_in
= lttv_state_find_process(tfs
, pid_in
);
306 if(process_in
== NULL
) return 0;
307 g_debug("in : %s",g_quark_to_string(process_in
->state
->s
));
309 birth
= process_in
->creation_time
;
310 name
= strdup(g_quark_to_string(process_in
->name
));
311 HashedProcessData
*hashed_process_data_in
= NULL
;
313 if(processlist_get_process_pixels(process_list
,
316 tfc
->t_context
->index
,
319 &hashed_process_data_in
) == 1)
321 /* Process not present */
322 processlist_add(process_list
,
325 tfc
->t_context
->index
,
328 &hashed_process_data_in
);
329 processlist_get_process_pixels(process_list
,
332 tfc
->t_context
->index
,
335 &hashed_process_data_in
);
337 drawing_insert_square( control_flow_data
->drawing
, y_in
, height
);
342 /* Find pixels corresponding to time of the event. If the time does
343 * not fit in the window, show a warning, not supposed to happend. */
345 guint width
= control_flow_data
->drawing
->drawing_area
->allocation
.width
;
347 LttTime time
= ltt_event_time(e
);
349 LttTime window_end
= ltt_time_add(time_window
.time_width
,
350 time_window
.start_time
);
353 convert_time_to_pixels(
354 time_window
.start_time
,
359 //assert(x <= width);
361 /* draw what represents the event for outgoing process. */
363 DrawContext
*draw_context_out
= hashed_process_data_out
->draw_context
;
364 draw_context_out
->current
->modify_over
->x
= x
;
365 draw_context_out
->current
->modify_under
->x
= x
;
366 draw_context_out
->current
->modify_over
->y
= y_out
;
367 draw_context_out
->current
->modify_under
->y
= y_out
+(height
/2)+2;
368 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
369 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
370 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
371 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
372 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
373 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
374 //draw_context_out->gc = widget->style->black_gc;
376 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
377 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
379 /* Draw the line/background of the out process */
380 if(draw_context_out
->previous
->middle
->x
== -1)
382 draw_context_out
->previous
->over
->x
=
383 control_flow_data
->drawing
->damage_begin
;
384 draw_context_out
->previous
->middle
->x
=
385 control_flow_data
->drawing
->damage_begin
;
386 draw_context_out
->previous
->under
->x
=
387 control_flow_data
->drawing
->damage_begin
;
389 g_debug("out middle x_beg : %u",control_flow_data
->drawing
->damage_begin
);
392 draw_context_out
->current
->middle
->x
= x
;
393 draw_context_out
->current
->over
->x
= x
;
394 draw_context_out
->current
->under
->x
= x
;
395 draw_context_out
->current
->middle
->y
= y_out
+ height
/2;
396 draw_context_out
->current
->over
->y
= y_out
;
397 draw_context_out
->current
->under
->y
= y_out
+ height
;
398 draw_context_out
->previous
->middle
->y
= y_out
+ height
/2;
399 draw_context_out
->previous
->over
->y
= y_out
;
400 draw_context_out
->previous
->under
->y
= y_out
+ height
;
402 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
403 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
405 if(process_out
->state
->s
== LTTV_STATE_RUN
)
407 draw_context_out
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
408 gdk_gc_copy(draw_context_out
->gc
, widget
->style
->black_gc
);
410 PropertiesBG prop_bg
;
411 prop_bg
.color
= g_new(GdkColor
,1);
415 prop_bg
.color
->red
= 0x1515;
416 prop_bg
.color
->green
= 0x1515;
417 prop_bg
.color
->blue
= 0x8c8c;
420 prop_bg
.color
->red
= 0x4e4e;
421 prop_bg
.color
->green
= 0xa9a9;
422 prop_bg
.color
->blue
= 0xa4a4;
425 prop_bg
.color
->red
= 0x7a7a;
426 prop_bg
.color
->green
= 0x4a4a;
427 prop_bg
.color
->blue
= 0x8b8b;
430 prop_bg
.color
->red
= 0x8080;
431 prop_bg
.color
->green
= 0x7777;
432 prop_bg
.color
->blue
= 0x4747;
435 prop_bg
.color
->red
= 0xe7e7;
436 prop_bg
.color
->green
= 0xe7e7;
437 prop_bg
.color
->blue
= 0xe7e7;
440 g_debug("calling from draw_event");
441 draw_bg((void*)&prop_bg
, (void*)draw_context_out
);
442 g_free(prop_bg
.color
);
443 gdk_gc_unref(draw_context_out
->gc
);
446 draw_context_out
->gc
= widget
->style
->black_gc
;
448 GdkColor colorfg_out
= { 0, 0xffff, 0x0000, 0x0000 };
449 GdkColor colorbg_out
= { 0, 0x0000, 0x0000, 0x0000 };
450 PropertiesText prop_text_out
;
451 prop_text_out
.foreground
= &colorfg_out
;
452 prop_text_out
.background
= &colorbg_out
;
453 prop_text_out
.size
= 6;
454 prop_text_out
.position
= OVER
;
456 /* color of text : status of the process */
457 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
459 prop_text_out
.foreground
->red
= 0xffff;
460 prop_text_out
.foreground
->green
= 0xffff;
461 prop_text_out
.foreground
->blue
= 0xffff;
463 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
465 prop_text_out
.foreground
->red
= 0x0fff;
466 prop_text_out
.foreground
->green
= 0xffff;
467 prop_text_out
.foreground
->blue
= 0xfff0;
469 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
471 prop_text_out
.foreground
->red
= 0xffff;
472 prop_text_out
.foreground
->green
= 0xffff;
473 prop_text_out
.foreground
->blue
= 0x0000;
475 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
477 prop_text_out
.foreground
->red
= 0xffff;
478 prop_text_out
.foreground
->green
= 0x0000;
479 prop_text_out
.foreground
->blue
= 0xffff;
481 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
483 prop_text_out
.foreground
->red
= 0xffff;
484 prop_text_out
.foreground
->green
= 0x0000;
485 prop_text_out
.foreground
->blue
= 0x0000;
487 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
489 prop_text_out
.foreground
->red
= 0x0000;
490 prop_text_out
.foreground
->green
= 0xffff;
491 prop_text_out
.foreground
->blue
= 0x0000;
495 prop_text_out
.foreground
->red
= 0xffff;
496 prop_text_out
.foreground
->green
= 0xffff;
497 prop_text_out
.foreground
->blue
= 0xffff;
501 /* Print status of the process : U, WF, WC, E, W, R */
502 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
503 prop_text_out
.text
= "U->";
504 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
505 prop_text_out
.text
= "WF->";
506 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
507 prop_text_out
.text
= "WC->";
508 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
509 prop_text_out
.text
= "E->";
510 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
511 prop_text_out
.text
= "W->";
512 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
513 prop_text_out
.text
= "R->";
515 prop_text_out
.text
= "U";
517 draw_text((void*)&prop_text_out
, (void*)draw_context_out
);
518 //gdk_gc_unref(draw_context_out->gc);
520 draw_context_out
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
521 gdk_gc_copy(draw_context_out
->gc
, widget
->style
->black_gc
);
523 PropertiesLine prop_line_out
;
524 prop_line_out
.color
= g_new(GdkColor
,1);
525 prop_line_out
.line_width
= 2;
526 prop_line_out
.style
= GDK_LINE_SOLID
;
527 prop_line_out
.position
= MIDDLE
;
529 g_debug("out state : %s", g_quark_to_string(process_out
->state
->s
));
531 /* color of line : status of the process */
532 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
534 prop_line_out
.color
->red
= 0xffff;
535 prop_line_out
.color
->green
= 0xffff;
536 prop_line_out
.color
->blue
= 0xffff;
538 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
540 prop_line_out
.color
->red
= 0x0fff;
541 prop_line_out
.color
->green
= 0xffff;
542 prop_line_out
.color
->blue
= 0xfff0;
544 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
546 prop_line_out
.color
->red
= 0xffff;
547 prop_line_out
.color
->green
= 0xffff;
548 prop_line_out
.color
->blue
= 0x0000;
550 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
552 prop_line_out
.color
->red
= 0xffff;
553 prop_line_out
.color
->green
= 0x0000;
554 prop_line_out
.color
->blue
= 0xffff;
556 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
558 prop_line_out
.color
->red
= 0xffff;
559 prop_line_out
.color
->green
= 0x0000;
560 prop_line_out
.color
->blue
= 0x0000;
562 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
564 prop_line_out
.color
->red
= 0x0000;
565 prop_line_out
.color
->green
= 0xffff;
566 prop_line_out
.color
->blue
= 0x0000;
570 prop_line_out
.color
->red
= 0xffff;
571 prop_line_out
.color
->green
= 0xffff;
572 prop_line_out
.color
->blue
= 0xffff;
575 draw_line((void*)&prop_line_out
, (void*)draw_context_out
);
576 g_free(prop_line_out
.color
);
577 gdk_gc_unref(draw_context_out
->gc
);
578 /* Note : finishing line will have to be added when trace read over. */
580 /* Finally, update the drawing context of the pid_in. */
582 DrawContext
*draw_context_in
= hashed_process_data_in
->draw_context
;
583 draw_context_in
->current
->modify_over
->x
= x
;
584 draw_context_in
->current
->modify_under
->x
= x
;
585 draw_context_in
->current
->modify_over
->y
= y_in
;
586 draw_context_in
->current
->modify_under
->y
= y_in
+(height
/2)+2;
587 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
588 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
589 widget
= control_flow_data
->drawing
->drawing_area
;
590 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
591 //draw_context_in->gc = widget->style->black_gc;
592 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
593 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
595 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
596 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
598 /* Draw the line/bg of the in process */
599 if(draw_context_in
->previous
->middle
->x
== -1)
601 draw_context_in
->previous
->over
->x
=
602 control_flow_data
->drawing
->damage_begin
;
603 draw_context_in
->previous
->middle
->x
=
604 control_flow_data
->drawing
->damage_begin
;
605 draw_context_in
->previous
->under
->x
=
606 control_flow_data
->drawing
->damage_begin
;
608 g_debug("in middle x_beg : %u",control_flow_data
->drawing
->damage_begin
);
612 draw_context_in
->current
->middle
->x
= x
;
613 draw_context_in
->current
->over
->x
= x
;
614 draw_context_in
->current
->under
->x
= x
;
615 draw_context_in
->current
->middle
->y
= y_in
+ height
/2;
616 draw_context_in
->current
->over
->y
= y_in
;
617 draw_context_in
->current
->under
->y
= y_in
+ height
;
618 draw_context_in
->previous
->middle
->y
= y_in
+ height
/2;
619 draw_context_in
->previous
->over
->y
= y_in
;
620 draw_context_in
->previous
->under
->y
= y_in
+ height
;
622 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
623 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
626 if(process_in
->state
->s
== LTTV_STATE_RUN
)
628 draw_context_in
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
629 gdk_gc_copy(draw_context_in
->gc
, widget
->style
->black_gc
);
631 PropertiesBG prop_bg
;
632 prop_bg
.color
= g_new(GdkColor
,1);
636 prop_bg
.color
->red
= 0x1515;
637 prop_bg
.color
->green
= 0x1515;
638 prop_bg
.color
->blue
= 0x8c8c;
641 prop_bg
.color
->red
= 0x4e4e;
642 prop_bg
.color
->green
= 0xa9a9;
643 prop_bg
.color
->blue
= 0xa4a4;
646 prop_bg
.color
->red
= 0x7a7a;
647 prop_bg
.color
->green
= 0x4a4a;
648 prop_bg
.color
->blue
= 0x8b8b;
651 prop_bg
.color
->red
= 0x8080;
652 prop_bg
.color
->green
= 0x7777;
653 prop_bg
.color
->blue
= 0x4747;
656 prop_bg
.color
->red
= 0xe7e7;
657 prop_bg
.color
->green
= 0xe7e7;
658 prop_bg
.color
->blue
= 0xe7e7;
662 draw_bg((void*)&prop_bg
, (void*)draw_context_in
);
663 g_free(prop_bg
.color
);
664 gdk_gc_unref(draw_context_in
->gc
);
667 draw_context_in
->gc
= widget
->style
->black_gc
;
669 GdkColor colorfg_in
= { 0, 0x0000, 0xffff, 0x0000 };
670 GdkColor colorbg_in
= { 0, 0x0000, 0x0000, 0x0000 };
671 PropertiesText prop_text_in
;
672 prop_text_in
.foreground
= &colorfg_in
;
673 prop_text_in
.background
= &colorbg_in
;
674 prop_text_in
.size
= 6;
675 prop_text_in
.position
= OVER
;
677 g_debug("in state : %s", g_quark_to_string(process_in
->state
->s
));
678 /* foreground of text : status of the process */
679 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
681 prop_text_in
.foreground
->red
= 0xffff;
682 prop_text_in
.foreground
->green
= 0xffff;
683 prop_text_in
.foreground
->blue
= 0xffff;
685 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
687 prop_text_in
.foreground
->red
= 0x0fff;
688 prop_text_in
.foreground
->green
= 0xffff;
689 prop_text_in
.foreground
->blue
= 0xfff0;
691 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
693 prop_text_in
.foreground
->red
= 0xffff;
694 prop_text_in
.foreground
->green
= 0xffff;
695 prop_text_in
.foreground
->blue
= 0x0000;
697 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
699 prop_text_in
.foreground
->red
= 0xffff;
700 prop_text_in
.foreground
->green
= 0x0000;
701 prop_text_in
.foreground
->blue
= 0xffff;
703 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
705 prop_text_in
.foreground
->red
= 0xffff;
706 prop_text_in
.foreground
->green
= 0x0000;
707 prop_text_in
.foreground
->blue
= 0x0000;
709 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
711 prop_text_in
.foreground
->red
= 0x0000;
712 prop_text_in
.foreground
->green
= 0xffff;
713 prop_text_in
.foreground
->blue
= 0x0000;
717 prop_text_in
.foreground
->red
= 0xffff;
718 prop_text_in
.foreground
->green
= 0xffff;
719 prop_text_in
.foreground
->blue
= 0xffff;
724 /* Print status of the process : U, WF, WC, E, W, R */
725 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
726 prop_text_in
.text
= "U->";
727 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
728 prop_text_in
.text
= "WF->";
729 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
730 prop_text_in
.text
= "WC->";
731 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
732 prop_text_in
.text
= "E->";
733 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
734 prop_text_in
.text
= "W->";
735 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
736 prop_text_in
.text
= "R->";
738 prop_text_in
.text
= "U";
740 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
741 //gdk_gc_unref(draw_context_in->gc);
743 draw_context_in
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
744 gdk_gc_copy(draw_context_in
->gc
, widget
->style
->black_gc
);
746 PropertiesLine prop_line_in
;
747 prop_line_in
.color
= g_new(GdkColor
,1);
748 prop_line_in
.line_width
= 2;
749 prop_line_in
.style
= GDK_LINE_SOLID
;
750 prop_line_in
.position
= MIDDLE
;
752 /* color of line : status of the process */
753 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
755 prop_line_in
.color
->red
= 0xffff;
756 prop_line_in
.color
->green
= 0xffff;
757 prop_line_in
.color
->blue
= 0xffff;
759 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
761 prop_line_in
.color
->red
= 0x0fff;
762 prop_line_in
.color
->green
= 0xffff;
763 prop_line_in
.color
->blue
= 0xfff0;
765 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
767 prop_line_in
.color
->red
= 0xffff;
768 prop_line_in
.color
->green
= 0xffff;
769 prop_line_in
.color
->blue
= 0x0000;
771 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
773 prop_line_in
.color
->red
= 0xffff;
774 prop_line_in
.color
->green
= 0x0000;
775 prop_line_in
.color
->blue
= 0xffff;
777 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
779 prop_line_in
.color
->red
= 0xffff;
780 prop_line_in
.color
->green
= 0x0000;
781 prop_line_in
.color
->blue
= 0x0000;
783 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
785 prop_line_in
.color
->red
= 0x0000;
786 prop_line_in
.color
->green
= 0xffff;
787 prop_line_in
.color
->blue
= 0x0000;
791 prop_line_in
.color
->red
= 0xffff;
792 prop_line_in
.color
->green
= 0xffff;
793 prop_line_in
.color
->blue
= 0xffff;
796 draw_line((void*)&prop_line_in
, (void*)draw_context_in
);
797 g_free(prop_line_in
.color
);
798 gdk_gc_unref(draw_context_in
->gc
);
805 GString
*string
= g_string_new("");;
806 gboolean field_names
= TRUE
, state
= TRUE
;
808 lttv_event_to_string(e
, tfc
->tf
, string
, TRUE
, field_names
, tfs
);
809 g_string_append_printf(string
,"\n");
812 g_string_append_printf(string
, " %s",
813 g_quark_to_string(tfs
->process
->state
->s
));
816 g_info("%s",string
->str
);
818 g_string_free(string
, TRUE
);
820 /* End of text dump */
826 int draw_after_hook(void *hook_data
, void *call_data
)
828 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
829 ControlFlowData
*control_flow_data
= events_request
->viewer_data
;
831 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
833 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
834 LttvTraceState
*ts
=(LttvTraceState
*)LTTV_TRACEFILE_CONTEXT(tfs
)->t_context
;
840 LttTime evtime
= ltt_event_time(e
);
841 TimeWindow time_window
=
842 lttvwindow_get_time_window(control_flow_data
->tab
);
844 LttTime end_time
= ltt_time_add(time_window
.start_time
,
845 time_window
.time_width
);
846 //if(time < time_beg || time > time_end) return;
847 if(ltt_time_compare(evtime
, time_window
.start_time
) == -1
848 || ltt_time_compare(evtime
, end_time
) == 1)
852 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e
)),"schedchange") == 0)
854 g_debug("schedchange!");
856 /* Add process to process list (if not present) and get drawing "y" from
857 * process position */
858 guint pid_out
, pid_in
;
859 LttvProcessState
*process_out
, *process_in
;
861 guint y_in
= 0, y_out
= 0, height
= 0, pl_height
= 0;
863 ProcessList
*process_list
=
864 guicontrolflow_get_process_list(control_flow_data
);
867 LttField
*f
= ltt_event_field(e
);
869 element
= ltt_field_member(f
,0);
870 pid_out
= ltt_event_get_long_unsigned(e
,element
);
871 element
= ltt_field_member(f
,1);
872 pid_in
= ltt_event_get_long_unsigned(e
,element
);
873 //g_debug("out : %u in : %u", pid_out, pid_in);
876 /* Find process pid_out in the list... */
877 process_out
= lttv_state_find_process(tfs
, pid_out
);
878 if(process_out
== NULL
) return 0;
879 //g_debug("out : %s",g_quark_to_string(process_out->state->s));
881 birth
= process_out
->creation_time
;
882 gchar
*name
= strdup(g_quark_to_string(process_out
->name
));
883 HashedProcessData
*hashed_process_data_out
= NULL
;
885 if(processlist_get_process_pixels(process_list
,
888 tfc
->t_context
->index
,
891 &hashed_process_data_out
) == 1)
893 /* Process not present */
894 processlist_add(process_list
,
897 tfc
->t_context
->index
,
900 &hashed_process_data_out
);
901 processlist_get_process_pixels(process_list
,
904 tfc
->t_context
->index
,
907 &hashed_process_data_out
);
908 drawing_insert_square( control_flow_data
->drawing
, y_out
, height
);
913 /* Find process pid_in in the list... */
914 process_in
= lttv_state_find_process(tfs
, pid_in
);
915 if(process_in
== NULL
) return 0;
916 //g_debug("in : %s",g_quark_to_string(process_in->state->s));
918 birth
= process_in
->creation_time
;
919 name
= strdup(g_quark_to_string(process_in
->name
));
920 HashedProcessData
*hashed_process_data_in
= NULL
;
922 if(processlist_get_process_pixels(process_list
,
925 tfc
->t_context
->index
,
928 &hashed_process_data_in
) == 1)
930 /* Process not present */
931 processlist_add(process_list
,
934 tfc
->t_context
->index
,
937 &hashed_process_data_in
);
938 processlist_get_process_pixels(process_list
,
941 tfc
->t_context
->index
,
944 &hashed_process_data_in
);
946 drawing_insert_square( control_flow_data
->drawing
, y_in
, height
);
951 /* Find pixels corresponding to time of the event. If the time does
952 * not fit in the window, show a warning, not supposed to happend. */
954 //guint width = control_flow_data->drawing->drawing_area->allocation.width;
956 //LttTime time = ltt_event_time(e);
958 //LttTime window_end = ltt_time_add(time_window->time_width,
959 // time_window->start_time);
962 //convert_time_to_pixels(
963 // time_window->start_time,
969 //assert(x <= width);
971 /* draw what represents the event for outgoing process. */
973 DrawContext
*draw_context_out
= hashed_process_data_out
->draw_context
;
974 //draw_context_out->current->modify_over->x = x;
975 draw_context_out
->current
->modify_over
->y
= y_out
;
976 draw_context_out
->current
->modify_under
->y
= y_out
+(height
/2)+2;
977 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
978 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
979 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
980 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
982 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
983 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
985 /*if(process_out->state->s == LTTV_STATE_RUN)
987 draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
988 gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
989 PropertiesBG prop_bg;
990 prop_bg.color = g_new(GdkColor,1);
992 prop_bg.color->red = 0xffff;
993 prop_bg.color->green = 0xffff;
994 prop_bg.color->blue = 0xffff;
996 draw_bg((void*)&prop_bg, (void*)draw_context_out);
997 g_free(prop_bg.color);
998 gdk_gc_unref(draw_context_out->gc);
1001 draw_context_out
->gc
= widget
->style
->black_gc
;
1003 GdkColor colorfg_out
= { 0, 0xffff, 0x0000, 0x0000 };
1004 GdkColor colorbg_out
= { 0, 0x0000, 0x0000, 0x0000 };
1005 PropertiesText prop_text_out
;
1006 prop_text_out
.foreground
= &colorfg_out
;
1007 prop_text_out
.background
= &colorbg_out
;
1008 prop_text_out
.size
= 6;
1009 prop_text_out
.position
= OVER
;
1011 /* color of text : status of the process */
1012 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
1014 prop_text_out
.foreground
->red
= 0xffff;
1015 prop_text_out
.foreground
->green
= 0xffff;
1016 prop_text_out
.foreground
->blue
= 0xffff;
1018 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
1020 prop_text_out
.foreground
->red
= 0x0fff;
1021 prop_text_out
.foreground
->green
= 0xffff;
1022 prop_text_out
.foreground
->blue
= 0xfff0;
1024 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
1026 prop_text_out
.foreground
->red
= 0xffff;
1027 prop_text_out
.foreground
->green
= 0xffff;
1028 prop_text_out
.foreground
->blue
= 0x0000;
1030 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
1032 prop_text_out
.foreground
->red
= 0xffff;
1033 prop_text_out
.foreground
->green
= 0x0000;
1034 prop_text_out
.foreground
->blue
= 0xffff;
1036 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
1038 prop_text_out
.foreground
->red
= 0xffff;
1039 prop_text_out
.foreground
->green
= 0x0000;
1040 prop_text_out
.foreground
->blue
= 0x0000;
1042 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
1044 prop_text_out
.foreground
->red
= 0x0000;
1045 prop_text_out
.foreground
->green
= 0xffff;
1046 prop_text_out
.foreground
->blue
= 0x0000;
1050 prop_text_out
.foreground
->red
= 0xffff;
1051 prop_text_out
.foreground
->green
= 0xffff;
1052 prop_text_out
.foreground
->blue
= 0xffff;
1055 /* Print status of the process : U, WF, WC, E, W, R */
1056 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
1057 prop_text_out
.text
= "U";
1058 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
1059 prop_text_out
.text
= "WF";
1060 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
1061 prop_text_out
.text
= "WC";
1062 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
1063 prop_text_out
.text
= "E";
1064 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
1065 prop_text_out
.text
= "W";
1066 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
1067 prop_text_out
.text
= "R";
1069 prop_text_out
.text
= "U";
1071 draw_text((void*)&prop_text_out
, (void*)draw_context_out
);
1073 //gdk_gc_unref(draw_context_out->gc);
1075 draw_context_out
->current
->middle
->y
= y_out
+height
/2;
1076 draw_context_out
->current
->over
->y
= y_out
;
1077 draw_context_out
->current
->under
->y
= y_out
+height
;
1078 draw_context_out
->current
->status
= process_out
->state
->s
;
1080 /* for pid_out : remove previous, Prev = current, new current (default) */
1081 g_free(draw_context_out
->previous
->modify_under
);
1082 g_free(draw_context_out
->previous
->modify_middle
);
1083 g_free(draw_context_out
->previous
->modify_over
);
1084 g_free(draw_context_out
->previous
->under
);
1085 g_free(draw_context_out
->previous
->middle
);
1086 g_free(draw_context_out
->previous
->over
);
1087 g_free(draw_context_out
->previous
);
1089 draw_context_out
->previous
= draw_context_out
->current
;
1091 draw_context_out
->current
= g_new(DrawInfo
,1);
1092 draw_context_out
->current
->over
= g_new(ItemInfo
,1);
1093 draw_context_out
->current
->over
->x
= -1;
1094 draw_context_out
->current
->over
->y
= -1;
1095 draw_context_out
->current
->middle
= g_new(ItemInfo
,1);
1096 draw_context_out
->current
->middle
->x
= -1;
1097 draw_context_out
->current
->middle
->y
= -1;
1098 draw_context_out
->current
->under
= g_new(ItemInfo
,1);
1099 draw_context_out
->current
->under
->x
= -1;
1100 draw_context_out
->current
->under
->y
= -1;
1101 draw_context_out
->current
->modify_over
= g_new(ItemInfo
,1);
1102 draw_context_out
->current
->modify_over
->x
= -1;
1103 draw_context_out
->current
->modify_over
->y
= -1;
1104 draw_context_out
->current
->modify_middle
= g_new(ItemInfo
,1);
1105 draw_context_out
->current
->modify_middle
->x
= -1;
1106 draw_context_out
->current
->modify_middle
->y
= -1;
1107 draw_context_out
->current
->modify_under
= g_new(ItemInfo
,1);
1108 draw_context_out
->current
->modify_under
->x
= -1;
1109 draw_context_out
->current
->modify_under
->y
= -1;
1110 draw_context_out
->current
->status
= LTTV_STATE_UNNAMED
;
1112 /* Finally, update the drawing context of the pid_in. */
1114 DrawContext
*draw_context_in
= hashed_process_data_in
->draw_context
;
1115 //draw_context_in->current->modify_over->x = x;
1116 draw_context_in
->current
->modify_over
->y
= y_in
;
1117 draw_context_in
->current
->modify_under
->y
= y_in
+(height
/2)+2;
1118 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
1119 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
1120 widget
= control_flow_data
->drawing
->drawing_area
;
1121 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
1123 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
1124 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
1126 /*if(process_in->state->s == LTTV_STATE_RUN)
1128 draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1129 gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
1130 PropertiesBG prop_bg;
1131 prop_bg.color = g_new(GdkColor,1);
1133 prop_bg.color->red = 0xffff;
1134 prop_bg.color->green = 0xffff;
1135 prop_bg.color->blue = 0xffff;
1137 draw_bg((void*)&prop_bg, (void*)draw_context_in);
1138 g_free(prop_bg.color);
1139 gdk_gc_unref(draw_context_in->gc);
1142 draw_context_in
->gc
= widget
->style
->black_gc
;
1144 GdkColor colorfg_in
= { 0, 0x0000, 0xffff, 0x0000 };
1145 GdkColor colorbg_in
= { 0, 0x0000, 0x0000, 0x0000 };
1146 PropertiesText prop_text_in
;
1147 prop_text_in
.foreground
= &colorfg_in
;
1148 prop_text_in
.background
= &colorbg_in
;
1149 prop_text_in
.size
= 6;
1150 prop_text_in
.position
= OVER
;
1152 /* foreground of text : status of the process */
1153 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
1155 prop_text_in
.foreground
->red
= 0xffff;
1156 prop_text_in
.foreground
->green
= 0xffff;
1157 prop_text_in
.foreground
->blue
= 0xffff;
1159 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
1161 prop_text_in
.foreground
->red
= 0x0fff;
1162 prop_text_in
.foreground
->green
= 0xffff;
1163 prop_text_in
.foreground
->blue
= 0xfff0;
1165 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
1167 prop_text_in
.foreground
->red
= 0xffff;
1168 prop_text_in
.foreground
->green
= 0xffff;
1169 prop_text_in
.foreground
->blue
= 0x0000;
1171 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
1173 prop_text_in
.foreground
->red
= 0xffff;
1174 prop_text_in
.foreground
->green
= 0x0000;
1175 prop_text_in
.foreground
->blue
= 0xffff;
1177 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
1179 prop_text_in
.foreground
->red
= 0xffff;
1180 prop_text_in
.foreground
->green
= 0x0000;
1181 prop_text_in
.foreground
->blue
= 0x0000;
1183 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
1185 prop_text_in
.foreground
->red
= 0x0000;
1186 prop_text_in
.foreground
->green
= 0xffff;
1187 prop_text_in
.foreground
->blue
= 0x0000;
1191 prop_text_in
.foreground
->red
= 0xffff;
1192 prop_text_in
.foreground
->green
= 0xffff;
1193 prop_text_in
.foreground
->blue
= 0xffff;
1197 /* Print status of the process : U, WF, WC, E, W, R */
1198 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
1199 prop_text_in
.text
= "U";
1200 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
1201 prop_text_in
.text
= "WF";
1202 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
1203 prop_text_in
.text
= "WC";
1204 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
1205 prop_text_in
.text
= "E";
1206 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
1207 prop_text_in
.text
= "W";
1208 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
1209 prop_text_in
.text
= "R";
1211 prop_text_in
.text
= "U";
1213 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
1216 if(process_in
->state
->s
== LTTV_STATE_RUN
)
1219 prop_text_in
.foreground
= &colorfg_in
;
1220 prop_text_in
.background
= &colorbg_in
;
1221 prop_text_in
.foreground
->red
= 0xffff;
1222 prop_text_in
.foreground
->green
= 0xffff;
1223 prop_text_in
.foreground
->blue
= 0xffff;
1224 prop_text_in
.size
= 6;
1225 prop_text_in
.position
= UNDER
;
1227 prop_text_in
.text
= g_new(gchar
, 260);
1228 strcpy(prop_text_in
.text
, "CPU ");
1229 snprintf(tmp
, 255, "%u", tfc
->index
);
1230 strcat(prop_text_in
.text
, tmp
);
1232 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
1233 g_free(prop_text_in
.text
);
1237 draw_context_in
->current
->middle
->y
= y_in
+height
/2;
1238 draw_context_in
->current
->over
->y
= y_in
;
1239 draw_context_in
->current
->under
->y
= y_in
+height
;
1240 draw_context_in
->current
->status
= process_in
->state
->s
;
1242 /* for pid_in : remove previous, Prev = current, new current (default) */
1243 g_free(draw_context_in
->previous
->modify_under
);
1244 g_free(draw_context_in
->previous
->modify_middle
);
1245 g_free(draw_context_in
->previous
->modify_over
);
1246 g_free(draw_context_in
->previous
->under
);
1247 g_free(draw_context_in
->previous
->middle
);
1248 g_free(draw_context_in
->previous
->over
);
1249 g_free(draw_context_in
->previous
);
1251 draw_context_in
->previous
= draw_context_in
->current
;
1253 draw_context_in
->current
= g_new(DrawInfo
,1);
1254 draw_context_in
->current
->over
= g_new(ItemInfo
,1);
1255 draw_context_in
->current
->over
->x
= -1;
1256 draw_context_in
->current
->over
->y
= -1;
1257 draw_context_in
->current
->middle
= g_new(ItemInfo
,1);
1258 draw_context_in
->current
->middle
->x
= -1;
1259 draw_context_in
->current
->middle
->y
= -1;
1260 draw_context_in
->current
->under
= g_new(ItemInfo
,1);
1261 draw_context_in
->current
->under
->x
= -1;
1262 draw_context_in
->current
->under
->y
= -1;
1263 draw_context_in
->current
->modify_over
= g_new(ItemInfo
,1);
1264 draw_context_in
->current
->modify_over
->x
= -1;
1265 draw_context_in
->current
->modify_over
->y
= -1;
1266 draw_context_in
->current
->modify_middle
= g_new(ItemInfo
,1);
1267 draw_context_in
->current
->modify_middle
->x
= -1;
1268 draw_context_in
->current
->modify_middle
->y
= -1;
1269 draw_context_in
->current
->modify_under
= g_new(ItemInfo
,1);
1270 draw_context_in
->current
->modify_under
->x
= -1;
1271 draw_context_in
->current
->modify_under
->y
= -1;
1272 draw_context_in
->current
->status
= LTTV_STATE_UNNAMED
;
1282 gint
update_time_window_hook(void *hook_data
, void *call_data
)
1284 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1285 Drawing_t
*drawing
= control_flow_data
->drawing
;
1287 const TimeWindowNotifyData
*time_window_nofify_data
=
1288 ((const TimeWindowNotifyData
*)call_data
);
1290 TimeWindow
*old_time_window
=
1291 time_window_nofify_data
->old_time_window
;
1292 TimeWindow
*new_time_window
=
1293 time_window_nofify_data
->new_time_window
;
1295 /* Update the ruler */
1296 drawing_update_ruler(control_flow_data
->drawing
,
1300 /* Two cases : zoom in/out or scrolling */
1302 /* In order to make sure we can reuse the old drawing, the scale must
1303 * be the same and the new time interval being partly located in the
1304 * currently shown time interval. (reuse is only for scrolling)
1307 g_info("Old time window HOOK : %u, %u to %u, %u",
1308 old_time_window
->start_time
.tv_sec
,
1309 old_time_window
->start_time
.tv_nsec
,
1310 old_time_window
->time_width
.tv_sec
,
1311 old_time_window
->time_width
.tv_nsec
);
1313 g_info("New time window HOOK : %u, %u to %u, %u",
1314 new_time_window
->start_time
.tv_sec
,
1315 new_time_window
->start_time
.tv_nsec
,
1316 new_time_window
->time_width
.tv_sec
,
1317 new_time_window
->time_width
.tv_nsec
);
1319 if( new_time_window
->time_width
.tv_sec
== old_time_window
->time_width
.tv_sec
1320 && new_time_window
->time_width
.tv_nsec
== old_time_window
->time_width
.tv_nsec
)
1322 /* Same scale (scrolling) */
1323 g_info("scrolling");
1324 LttTime
*ns
= &new_time_window
->start_time
;
1325 LttTime
*os
= &old_time_window
->start_time
;
1326 LttTime old_end
= ltt_time_add(old_time_window
->start_time
,
1327 old_time_window
->time_width
);
1328 LttTime new_end
= ltt_time_add(new_time_window
->start_time
,
1329 new_time_window
->time_width
);
1331 //if(ns<os+w && os+w<ns+w)
1332 //if(ns<old_end && os<ns)
1333 if(ltt_time_compare(*ns
, old_end
) == -1
1334 && ltt_time_compare(*os
, *ns
) == -1)
1336 g_info("scrolling near right");
1337 /* Scroll right, keep right part of the screen */
1339 guint width
= control_flow_data
->drawing
->drawing_area
->allocation
.width
;
1340 convert_time_to_pixels(
1347 /* Copy old data to new location */
1348 gdk_draw_drawable (control_flow_data
->drawing
->pixmap
,
1349 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1350 control_flow_data
->drawing
->pixmap
,
1353 control_flow_data
->drawing
->width
-x
+SAFETY
, -1);
1355 if(drawing
->damage_begin
== drawing
->damage_end
)
1356 drawing
->damage_begin
= control_flow_data
->drawing
->width
-x
;
1358 drawing
->damage_begin
= 0;
1360 drawing
->damage_end
= control_flow_data
->drawing
->width
;
1362 /* Clear the data request background, but not SAFETY */
1363 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1364 //control_flow_data->drawing->drawing_area->style->black_gc,
1365 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1367 drawing
->damage_begin
+SAFETY
, 0,
1368 drawing
->damage_end
- drawing
->damage_begin
, // do not overlap
1369 control_flow_data
->drawing
->height
+SAFETY
);
1371 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1373 control_flow_data
->drawing
->width
,
1374 control_flow_data
->drawing
->height
);
1376 /* Get new data for the rest. */
1377 drawing_data_request(control_flow_data
->drawing
,
1378 &control_flow_data
->drawing
->pixmap
,
1379 drawing
->damage_begin
, 0,
1380 drawing
->damage_end
- drawing
->damage_begin
,
1381 control_flow_data
->drawing
->height
);
1384 //if(ns<os && os<ns+w)
1385 //if(ns<os && os<new_end)
1386 if(ltt_time_compare(*ns
,*os
) == -1
1387 && ltt_time_compare(*os
,new_end
) == -1)
1389 g_info("scrolling near left");
1390 /* Scroll left, keep left part of the screen */
1392 guint width
= control_flow_data
->drawing
->drawing_area
->allocation
.width
;
1393 convert_time_to_pixels(
1401 /* Copy old data to new location */
1402 gdk_draw_drawable (control_flow_data
->drawing
->pixmap
,
1403 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1404 control_flow_data
->drawing
->pixmap
,
1409 *old_time_window
= *new_time_window
;
1411 if(drawing
->damage_begin
== drawing
->damage_end
)
1412 drawing
->damage_end
= x
;
1414 drawing
->damage_end
=
1415 control_flow_data
->drawing
->drawing_area
->allocation
.width
;
1417 drawing
->damage_begin
= 0;
1419 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1420 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1422 drawing
->damage_begin
, 0,
1423 drawing
->damage_end
- drawing
->damage_begin
, // do not overlap
1424 control_flow_data
->drawing
->height
+SAFETY
);
1426 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1428 control_flow_data
->drawing
->width
,
1429 control_flow_data
->drawing
->height
);
1432 /* Get new data for the rest. */
1433 drawing_data_request(control_flow_data
->drawing
,
1434 &control_flow_data
->drawing
->pixmap
,
1435 drawing
->damage_begin
, 0,
1436 drawing
->damage_end
- drawing
->damage_begin
,
1437 control_flow_data
->drawing
->height
);
1440 if(ltt_time_compare(*ns
,*os
) == 0)
1442 g_info("not scrolling");
1444 g_info("scrolling far");
1445 /* Cannot reuse any part of the screen : far jump */
1448 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1449 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1452 control_flow_data
->drawing
->width
+SAFETY
, // do not overlap
1453 control_flow_data
->drawing
->height
+SAFETY
);
1455 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1457 control_flow_data
->drawing
->width
,
1458 control_flow_data
->drawing
->height
);
1460 drawing
->damage_begin
= 0;
1461 drawing
->damage_end
= control_flow_data
->drawing
->width
;
1463 drawing_data_request(control_flow_data
->drawing
,
1464 &control_flow_data
->drawing
->pixmap
,
1466 control_flow_data
->drawing
->width
,
1467 control_flow_data
->drawing
->height
);
1473 /* Different scale (zoom) */
1476 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1477 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1480 control_flow_data
->drawing
->width
+SAFETY
, // do not overlap
1481 control_flow_data
->drawing
->height
+SAFETY
);
1483 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1485 control_flow_data
->drawing
->width
,
1486 control_flow_data
->drawing
->height
);
1488 drawing
->damage_begin
= 0;
1489 drawing
->damage_end
= control_flow_data
->drawing
->width
;
1491 drawing_data_request(control_flow_data
->drawing
,
1492 &control_flow_data
->drawing
->pixmap
,
1494 control_flow_data
->drawing
->width
,
1495 control_flow_data
->drawing
->height
);
1503 gint
traceset_notify(void *hook_data
, void *call_data
)
1505 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1506 Drawing_t
*drawing
= control_flow_data
->drawing
;
1507 GtkWidget
*widget
= drawing
->drawing_area
;
1509 drawing
->damage_begin
= 0;
1510 drawing
->damage_end
= widget
->allocation
.width
;
1514 gdk_draw_rectangle (drawing
->pixmap
,
1515 widget
->style
->black_gc
,
1518 widget
->allocation
.width
+SAFETY
,
1519 widget
->allocation
.height
+SAFETY
);
1522 if(drawing
->damage_begin
< drawing
->damage_end
)
1524 drawing_data_request(drawing
,
1526 drawing
->damage_begin
,
1528 drawing
->damage_end
-drawing
->damage_begin
,
1529 widget
->allocation
.height
);
1532 gtk_widget_queue_draw_area(drawing
->drawing_area
,
1537 request_background_data(control_flow_data
);
1542 gint
redraw_notify(void *hook_data
, void *call_data
)
1544 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1545 Drawing_t
*drawing
= control_flow_data
->drawing
;
1546 GtkWidget
*widget
= drawing
->drawing_area
;
1548 drawing
->damage_begin
= 0;
1549 drawing
->damage_end
= widget
->allocation
.width
;
1553 gdk_draw_rectangle (drawing
->pixmap
,
1554 widget
->style
->black_gc
,
1557 widget
->allocation
.width
+SAFETY
,
1558 widget
->allocation
.height
+SAFETY
);
1561 if(drawing
->damage_begin
< drawing
->damage_end
)
1563 drawing_data_request(drawing
,
1565 drawing
->damage_begin
,
1567 drawing
->damage_end
-drawing
->damage_begin
,
1568 widget
->allocation
.height
);
1571 gtk_widget_queue_draw_area(drawing
->drawing_area
,
1581 gint
continue_notify(void *hook_data
, void *call_data
)
1583 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1584 Drawing_t
*drawing
= control_flow_data
->drawing
;
1585 GtkWidget
*widget
= drawing
->drawing_area
;
1587 //g_assert(widget->allocation.width == drawing->damage_end);
1589 if(drawing
->damage_begin
< drawing
->damage_end
)
1591 drawing_data_request(drawing
,
1593 drawing
->damage_begin
,
1595 drawing
->damage_end
-drawing
->damage_begin
,
1596 widget
->allocation
.height
);
1603 gint
after_process_traceset_hook(void *hook_data
, void *call_data
)
1605 //ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
1606 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
1608 ControlFlowData
*control_flow_data
=
1609 (ControlFlowData
*)events_request
->viewer_data
;
1612 drawing_data_request_end(events_request
,
1613 (LttvTracesetState
*)call_data
);
1619 gint
update_current_time_hook(void *hook_data
, void *call_data
)
1621 ControlFlowData
*control_flow_data
= (ControlFlowData
*)hook_data
;
1622 Drawing_t
*drawing
= control_flow_data
->drawing
;
1624 LttTime current_time
= *((LttTime
*)call_data
);
1626 TimeWindow time_window
=
1627 lttvwindow_get_time_window(control_flow_data
->tab
);
1629 LttTime time_begin
= time_window
.start_time
;
1630 LttTime width
= time_window
.time_width
;
1631 LttTime half_width
= ltt_time_div(width
,2.0);
1632 LttTime time_end
= ltt_time_add(time_begin
, width
);
1634 LttvTracesetContext
* tsc
=
1635 lttvwindow_get_traceset_context(control_flow_data
->tab
);
1637 LttTime trace_start
= tsc
->time_span
.start_time
;
1638 LttTime trace_end
= tsc
->time_span
.end_time
;
1640 g_info("New current time HOOK : %u, %u", current_time
.tv_sec
,
1641 current_time
.tv_nsec
);
1645 /* If current time is inside time interval, just move the highlight
1648 /* Else, we have to change the time interval. We have to tell it
1649 * to the main window. */
1650 /* The time interval change will take care of placing the current
1651 * time at the center of the visible area, or nearest possible if we are
1652 * at one end of the trace. */
1655 if(ltt_time_compare(current_time
, time_begin
) == -1)
1657 TimeWindow new_time_window
;
1659 if(ltt_time_compare(current_time
,
1660 ltt_time_add(trace_start
,half_width
)) == -1)
1661 time_begin
= trace_start
;
1663 time_begin
= ltt_time_sub(current_time
,half_width
);
1665 new_time_window
.start_time
= time_begin
;
1666 new_time_window
.time_width
= width
;
1668 lttvwindow_report_time_window(control_flow_data
->tab
, &new_time_window
);
1670 else if(ltt_time_compare(current_time
, time_end
) == 1)
1672 TimeWindow new_time_window
;
1674 if(ltt_time_compare(current_time
, ltt_time_sub(trace_end
, half_width
)) == 1)
1675 time_begin
= ltt_time_sub(trace_end
,width
);
1677 time_begin
= ltt_time_sub(current_time
,half_width
);
1679 new_time_window
.start_time
= time_begin
;
1680 new_time_window
.time_width
= width
;
1682 lttvwindow_report_time_window(control_flow_data
->tab
, &new_time_window
);
1685 //gtk_widget_queue_draw(control_flow_data->drawing->drawing_area);
1686 gtk_widget_queue_draw_area(drawing
->drawing_area
,
1694 typedef struct _ClosureData
{
1695 EventsRequest
*events_request
;
1696 LttvTracesetState
*tss
;
1700 void draw_closure(gpointer key
, gpointer value
, gpointer user_data
)
1702 ProcessInfo
*process_info
= (ProcessInfo
*)key
;
1703 HashedProcessData
*hashed_process_data
= (HashedProcessData
*)value
;
1704 ClosureData
*closure_data
= (ClosureData
*)user_data
;
1706 ControlFlowData
*control_flow_data
=
1707 closure_data
->events_request
->viewer_data
;
1709 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
1711 /* Get y position of process */
1714 processlist_get_pixels_from_data( control_flow_data
->process_list
,
1716 hashed_process_data
,
1719 /* Get last state of process */
1720 LttvTraceContext
*tc
=
1721 ((LttvTracesetContext
*)closure_data
->tss
)->traces
[process_info
->trace_num
];
1722 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)closure_data
->tss
;
1724 LttvTraceState
*ts
= (LttvTraceState
*)tc
;
1725 LttvProcessState
*process
;
1727 /* We do not provide a cpu_name argument assuming that this is not the
1728 idle job (pid 0) and thus its pid is unique across all cpus */
1729 process
= lttv_state_find_process_from_trace(ts
, 0, process_info
->pid
);
1731 /* Draw the closing line */
1732 DrawContext
*draw_context
= hashed_process_data
->draw_context
;
1733 if(draw_context
->previous
->middle
->x
== -1)
1735 draw_context
->previous
->over
->x
=
1736 control_flow_data
->drawing
->damage_begin
;
1737 draw_context
->previous
->middle
->x
=
1738 control_flow_data
->drawing
->damage_begin
;
1739 draw_context
->previous
->under
->x
=
1740 control_flow_data
->drawing
->damage_begin
;
1742 g_debug("out middle x_beg : %u",control_flow_data
->drawing
->damage_begin
);
1745 /* Find pixels corresponding to current time . If the time does
1746 * not fit in the window, show a warning, not supposed to happend. */
1748 guint width
= control_flow_data
->drawing
->drawing_area
->allocation
.width
;
1750 TimeWindow time_window
=
1751 lttvwindow_get_time_window(control_flow_data
->tab
);
1753 LttTime time
= lttv_traceset_context_get_current_tfc(tsc
)->timestamp
;
1755 LttTime window_end
= ltt_time_add(time_window
.time_width
,
1756 time_window
.start_time
);
1758 convert_time_to_pixels(
1759 time_window
.start_time
,
1765 draw_context
->current
->middle
->x
= x
;
1766 draw_context
->current
->over
->x
= x
;
1767 draw_context
->current
->under
->x
= x
;
1768 draw_context
->current
->middle
->y
= y
+ height
/2;
1769 draw_context
->current
->over
->y
= y
;
1770 draw_context
->current
->under
->y
= y
+ height
;
1771 draw_context
->previous
->middle
->y
= y
+ height
/2;
1772 draw_context
->previous
->over
->y
= y
;
1773 draw_context
->previous
->under
->y
= y
+ height
;
1774 draw_context
->drawable
= control_flow_data
->drawing
->pixmap
;
1775 draw_context
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
1776 //draw_context->gc = widget->style->black_gc;
1777 draw_context
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
1778 gdk_gc_copy(draw_context
->gc
, widget
->style
->black_gc
);
1780 if(process
!= NULL
&& process
->state
->s
== LTTV_STATE_RUN
)
1782 PropertiesBG prop_bg
;
1783 prop_bg
.color
= g_new(GdkColor
,1);
1785 /*switch(tfc->index) {
1787 prop_bg.color->red = 0x1515;
1788 prop_bg.color->green = 0x1515;
1789 prop_bg.color->blue = 0x8c8c;
1792 prop_bg.color->red = 0x4e4e;
1793 prop_bg.color->green = 0xa9a9;
1794 prop_bg.color->blue = 0xa4a4;
1797 prop_bg.color->red = 0x7a7a;
1798 prop_bg.color->green = 0x4a4a;
1799 prop_bg.color->blue = 0x8b8b;
1802 prop_bg.color->red = 0x8080;
1803 prop_bg.color->green = 0x7777;
1804 prop_bg.color->blue = 0x4747;
1807 prop_bg.color->red = 0xe7e7;
1808 prop_bg.color->green = 0xe7e7;
1809 prop_bg.color->blue = 0xe7e7;
1813 g_debug("calling from closure");
1814 //FIXME : I need the cpu number in process's state to draw this.
1815 //draw_bg((void*)&prop_bg, (void*)draw_context);
1816 g_free(prop_bg
.color
);
1820 PropertiesLine prop_line
;
1821 prop_line
.color
= g_new(GdkColor
,1);
1822 prop_line
.line_width
= 2;
1823 prop_line
.style
= GDK_LINE_SOLID
;
1824 prop_line
.position
= MIDDLE
;
1826 /* color of line : status of the process */
1829 if(process
->state
->s
== LTTV_STATE_UNNAMED
)
1831 prop_line
.color
->red
= 0xffff;
1832 prop_line
.color
->green
= 0xffff;
1833 prop_line
.color
->blue
= 0xffff;
1835 else if(process
->state
->s
== LTTV_STATE_WAIT_FORK
)
1837 prop_line
.color
->red
= 0x0fff;
1838 prop_line
.color
->green
= 0xffff;
1839 prop_line
.color
->blue
= 0xfff0;
1841 else if(process
->state
->s
== LTTV_STATE_WAIT_CPU
)
1843 prop_line
.color
->red
= 0xffff;
1844 prop_line
.color
->green
= 0xffff;
1845 prop_line
.color
->blue
= 0x0000;
1847 else if(process
->state
->s
== LTTV_STATE_EXIT
)
1849 prop_line
.color
->red
= 0xffff;
1850 prop_line
.color
->green
= 0x0000;
1851 prop_line
.color
->blue
= 0xffff;
1853 else if(process
->state
->s
== LTTV_STATE_WAIT
)
1855 prop_line
.color
->red
= 0xffff;
1856 prop_line
.color
->green
= 0x0000;
1857 prop_line
.color
->blue
= 0x0000;
1859 else if(process
->state
->s
== LTTV_STATE_RUN
)
1861 prop_line
.color
->red
= 0x0000;
1862 prop_line
.color
->green
= 0xffff;
1863 prop_line
.color
->blue
= 0x0000;
1867 prop_line
.color
->red
= 0xffff;
1868 prop_line
.color
->green
= 0xffff;
1869 prop_line
.color
->blue
= 0xffff;
1875 prop_line
.color
->red
= 0xffff;
1876 prop_line
.color
->green
= 0xffff;
1877 prop_line
.color
->blue
= 0xffff;
1880 draw_line((void*)&prop_line
, (void*)draw_context
);
1881 g_free(prop_line
.color
);
1882 gdk_gc_unref(draw_context
->gc
);
1884 /* Reset draw_context of the process for next request */
1886 hashed_process_data
->draw_context
->drawable
= NULL
;
1887 hashed_process_data
->draw_context
->gc
= NULL
;
1888 hashed_process_data
->draw_context
->pango_layout
= NULL
;
1889 hashed_process_data
->draw_context
->current
->over
->x
= -1;
1890 hashed_process_data
->draw_context
->current
->over
->y
= -1;
1891 hashed_process_data
->draw_context
->current
->middle
->x
= -1;
1892 hashed_process_data
->draw_context
->current
->middle
->y
= -1;
1893 hashed_process_data
->draw_context
->current
->under
->x
= -1;
1894 hashed_process_data
->draw_context
->current
->under
->y
= -1;
1895 hashed_process_data
->draw_context
->current
->modify_over
->x
= -1;
1896 hashed_process_data
->draw_context
->current
->modify_over
->y
= -1;
1897 hashed_process_data
->draw_context
->current
->modify_middle
->x
= -1;
1898 hashed_process_data
->draw_context
->current
->modify_middle
->y
= -1;
1899 hashed_process_data
->draw_context
->current
->modify_under
->x
= -1;
1900 hashed_process_data
->draw_context
->current
->modify_under
->y
= -1;
1901 hashed_process_data
->draw_context
->current
->status
= LTTV_STATE_UNNAMED
;
1902 hashed_process_data
->draw_context
->previous
->over
->x
= -1;
1903 hashed_process_data
->draw_context
->previous
->over
->y
= -1;
1904 hashed_process_data
->draw_context
->previous
->middle
->x
= -1;
1905 hashed_process_data
->draw_context
->previous
->middle
->y
= -1;
1906 hashed_process_data
->draw_context
->previous
->under
->x
= -1;
1907 hashed_process_data
->draw_context
->previous
->under
->y
= -1;
1908 hashed_process_data
->draw_context
->previous
->modify_over
->x
= -1;
1909 hashed_process_data
->draw_context
->previous
->modify_over
->y
= -1;
1910 hashed_process_data
->draw_context
->previous
->modify_middle
->x
= -1;
1911 hashed_process_data
->draw_context
->previous
->modify_middle
->y
= -1;
1912 hashed_process_data
->draw_context
->previous
->modify_under
->x
= -1;
1913 hashed_process_data
->draw_context
->previous
->modify_under
->y
= -1;
1914 hashed_process_data
->draw_context
->previous
->status
= LTTV_STATE_UNNAMED
;
1918 int before_data_request(void *hook_data
, void *call_data
)
1920 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
1921 LttvTracesetState
*tss
= LTTV_TRACESET_STATE(call_data
);
1923 drawing_data_request_begin(events_request
, tss
);
1932 * new default prev and current
1933 * then finally remove reading hooks.
1935 int after_data_request(void *hook_data
, void *call_data
)
1937 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
1938 ControlFlowData
*control_flow_data
= events_request
->viewer_data
;
1939 LttvTracesetState
*tss
= LTTV_TRACESET_STATE(call_data
);
1941 ProcessList
*process_list
=
1942 guicontrolflow_get_process_list(control_flow_data
);
1944 ClosureData closure_data
;
1945 closure_data
.events_request
= (EventsRequest
*)hook_data
;
1946 closure_data
.tss
= tss
;
1948 g_hash_table_foreach(process_list
->process_hash
, draw_closure
,
1949 (void*)&closure_data
);
1951 /* Request expose */
1952 drawing_data_request_end(events_request
, tss
);