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 /* Event hooks are the drawing hooks called during traceset read. They draw the
26 * icons, text, lines and background color corresponding to the events read.
28 * Two hooks are used for drawing : draw_before and draw_after hooks. The
29 * draw_before is called before the state update that occurs with an event and
30 * the draw_after hook is called after this state update.
32 * The draw_before hooks fulfill the task of drawing the visible objects that
33 * corresponds to the data accumulated by the draw_after hook.
35 * The draw_after hook accumulates the data that need to be shown on the screen
36 * (items) into a queue. Then, the next draw_before hook will draw what that
37 * queue contains. That's the Right Way (TM) of drawing items on the screen,
38 * because we need to draw the background first (and then add icons, text, ...
39 * over it), but we only know the length of a background region once the state
40 * corresponding to it is over, which happens to be at the next draw_before
43 * We also have a hook called at the end of a chunk to draw the information left
44 * undrawn in each process queue. We use the current time as end of
49 //#define PANGO_ENABLE_BACKEND
57 //#include <pango/pango.h>
59 #include <ltt/event.h>
63 #include <lttv/lttv.h>
64 #include <lttv/hook.h>
65 #include <lttv/state.h>
66 #include <lttvwindow/lttvwindow.h>
67 #include <lttvwindow/lttvwindowtraces.h>
70 #include "eventhooks.h"
72 #include "processlist.h"
74 #include "cfv-private.h"
77 #define MAX_PATH_LEN 256
81 typedef struct _ProcessAddClosure
{
86 static void process_add(gpointer key
,
90 LttvProcessState
*process
= (LttvProcessState
*)value
;
91 ProcessAddClosure
*closure
= (ProcessAddClosure
*)user_data
;
92 ControlFlowData
*control_flow_data
= closure
->cfd
;
93 guint trace_num
= closure
->trace_num
;
95 /* Add process to process list (if not present) */
98 guint y
= 0, height
= 0, pl_height
= 0;
100 ProcessList
*process_list
=
101 guicontrolflow_get_process_list(control_flow_data
);
104 birth
= process
->creation_time
;
105 const gchar
*name
= g_quark_to_string(process
->name
);
106 HashedProcessData
*hashed_process_data
= NULL
;
108 if(processlist_get_process_pixels(process_list
,
114 &hashed_process_data
) == 1)
116 /* Process not present */
117 processlist_add(process_list
,
123 &hashed_process_data
);
124 processlist_get_process_pixels(process_list
,
130 &hashed_process_data
);
131 drawing_insert_square( control_flow_data
->drawing
, y
, height
);
137 /* Action to do when background computation completed.
139 * Eventually, will have to check that every requested traces are finished
140 * before doing the redraw. It will save unnecessary processor usage.
143 gint
background_ready(void *hook_data
, void *call_data
)
145 ControlFlowData
*control_flow_data
= (ControlFlowData
*)hook_data
;
146 LttvTrace
*trace
= (LttvTrace
*)call_data
;
147 LttvTracesetContext
*tsc
=
148 lttvwindow_get_traceset_context(control_flow_data
->tab
);
150 g_debug("control flow viewer : background computation data ready.");
152 drawing_clear(control_flow_data
->drawing
);
153 processlist_clear(control_flow_data
->process_list
);
156 gint num_traces
= lttv_traceset_number(tsc
->ts
);
159 ProcessAddClosure closure
;
160 closure
.cfd
= control_flow_data
;
162 for(i
=0;i
<num_traces
;i
++) {
163 ts
= (LttvTraceState
*)tsc
->traces
[i
];
165 closure
.trace_num
= i
;
167 /* add all the processes to the list */
168 lttv_state_for_each_process(ts
, (GHFunc
)process_add
, &closure
);
172 redraw_notify(control_flow_data
, NULL
);
178 /* Request background computation. Verify if it is in progress or ready first.
180 * Right now, for all loaded traces.
182 * Later : must be only for each trace in the tab's traceset.
184 void request_background_data(ControlFlowData
*control_flow_data
)
186 gint num_traces
= lttvwindowtraces_get_number();
190 LttvHooks
*background_ready_hook
=
192 lttv_hooks_add(background_ready_hook
, background_ready
, control_flow_data
,
195 for(i
=0;i
<num_traces
;i
++) {
196 trace
= lttvwindowtraces_get_trace(i
);
198 if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace
)==FALSE
) {
200 if(lttvwindowtraces_get_in_progress(g_quark_from_string("state"),
202 /* We first remove requests that could have been done for the same
203 * information. Happens when two viewers ask for it before servicing
206 lttvwindowtraces_background_request_remove(trace
, "state");
207 lttvwindowtraces_background_request_queue(trace
,
209 lttvwindowtraces_background_notify_queue(control_flow_data
,
213 background_ready_hook
);
214 } else { /* in progress */
216 lttvwindowtraces_background_notify_current(control_flow_data
,
220 background_ready_hook
);
226 lttv_hooks_destroy(background_ready_hook
);
233 * Event Viewer's constructor hook
235 * This constructor is given as a parameter to the menuitem and toolbar button
236 * registration. It creates the list.
237 * @param tab A pointer to the parent tab.
238 * @return The widget created.
241 h_guicontrolflow(Tab
*tab
, LttvTracesetSelector
* s
, char * key
)
243 g_info("h_guicontrolflow, %p, %p, %s", tab
, s
, key
);
244 ControlFlowData
*control_flow_data
= guicontrolflow() ;
246 control_flow_data
->tab
= tab
;
248 //g_debug("time width2 : %u",time_window->time_width);
249 // Unreg done in the GuiControlFlow_Destructor
250 lttvwindow_register_traceset_notify(tab
,
254 lttvwindow_register_time_window_notify(tab
,
255 update_time_window_hook
,
257 lttvwindow_register_current_time_notify(tab
,
258 update_current_time_hook
,
260 lttvwindow_register_redraw_notify(tab
,
263 lttvwindow_register_continue_notify(tab
,
266 request_background_data(control_flow_data
);
269 return guicontrolflow_get_widget(control_flow_data
) ;
273 int event_selected_hook(void *hook_data
, void *call_data
)
275 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
276 guint
*event_number
= (guint
*) call_data
;
278 g_debug("DEBUG : event selected by main window : %u", *event_number
);
283 static __inline PropertiesLine
prepare_line(LttvProcessState
*process
)
285 PropertiesLine prop_line
;
286 prop_line
.line_width
= 2;
287 prop_line
.style
= GDK_LINE_SOLID
;
288 prop_line
.position
= MIDDLE
;
290 g_debug("prepare_line for state : %s", g_quark_to_string(process
->state
->s
));
292 /* color of line : status of the process */
293 if(process
->state
->s
== LTTV_STATE_UNNAMED
)
295 prop_line
.color
.red
= 0xffff;
296 prop_line
.color
.green
= 0xffff;
297 prop_line
.color
.blue
= 0xffff;
299 else if(process
->state
->s
== LTTV_STATE_WAIT_FORK
)
301 prop_line
.color
.red
= 0x0fff;
302 prop_line
.color
.green
= 0xffff;
303 prop_line
.color
.blue
= 0xfff0;
305 else if(process
->state
->s
== LTTV_STATE_WAIT_CPU
)
307 prop_line
.color
.red
= 0xffff;
308 prop_line
.color
.green
= 0xffff;
309 prop_line
.color
.blue
= 0x0000;
311 else if(process
->state
->s
== LTTV_STATE_EXIT
)
313 prop_line
.color
.red
= 0xffff;
314 prop_line
.color
.green
= 0x0000;
315 prop_line
.color
.blue
= 0xffff;
317 else if(process
->state
->s
== LTTV_STATE_WAIT
)
319 prop_line
.color
.red
= 0xffff;
320 prop_line
.color
.green
= 0x0000;
321 prop_line
.color
.blue
= 0x0000;
323 else if(process
->state
->s
== LTTV_STATE_RUN
)
325 prop_line
.color
.red
= 0x0000;
326 prop_line
.color
.green
= 0xffff;
327 prop_line
.color
.blue
= 0x0000;
331 prop_line
.color
.red
= 0xffff;
332 prop_line
.color
.green
= 0xffff;
333 prop_line
.color
.blue
= 0xffff;
344 * This function basically draw lines and icons. Two types of lines are drawn :
345 * one small (3 pixels?) representing the state of the process and the second
346 * type is thicker (10 pixels?) representing on which CPU a process is running
347 * (and this only in running state).
349 * Extremums of the lines :
350 * x_min : time of the last event context for this process kept in memory.
351 * x_max : time of the current event.
352 * y : middle of the process in the process list. The process is found in the
353 * list, therefore is it's position in pixels.
355 * The choice of lines'color is defined by the context of the last event for this
360 int draw_before_hook(void *hook_data
, void *call_data
)
362 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
363 ControlFlowData
*control_flow_data
= events_request
->viewer_data
;
364 Drawing_t
*drawing
= control_flow_data
->drawing
;
366 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
368 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
369 LttvTraceState
*ts
=(LttvTraceState
*)LTTV_TRACEFILE_CONTEXT(tfs
)->t_context
;
374 LttTime evtime
= ltt_event_time(e
);
375 TimeWindow time_window
=
376 lttvwindow_get_time_window(control_flow_data
->tab
);
378 LttTime end_time
= ltt_time_add(time_window
.start_time
,
379 time_window
.time_width
);
381 if(ltt_time_compare(evtime
, time_window
.start_time
) == -1
382 || ltt_time_compare(evtime
, end_time
) == 1)
385 guint width
= drawing
->width
;
387 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e
)),"schedchange") == 0) {
389 /* we are in a schedchange, before the state update. We must draw the
390 * items corresponding to the state before it changes : now is the right
397 LttField
*f
= ltt_event_field(e
);
399 element
= ltt_field_member(f
,0);
400 pid_out
= ltt_event_get_long_unsigned(e
,element
);
401 element
= ltt_field_member(f
,1);
402 pid_in
= ltt_event_get_long_unsigned(e
,element
);
403 g_debug("out : %u in : %u", pid_out
, pid_in
);
406 /* First, check if the current process is in the state computation process
407 * list. If it is there, that means we must add it right now and draw items
408 * from the beginning of the read for it. If it is not present, it's a new
409 * process and it was not present : it will be added after the state update.
411 LttvProcessState
*process
;
412 process
= lttv_state_find_process(tfs
, pid_out
);
414 if(process
!= NULL
) {
415 /* Well, the process_out existed : we must get it in the process hash
416 * or add it, and draw its items.
418 /* Add process to process list (if not present) */
419 guint y
= 0, height
= 0, pl_height
= 0;
420 HashedProcessData
*hashed_process_data
= NULL
;
421 ProcessList
*process_list
=
422 guicontrolflow_get_process_list(control_flow_data
);
423 LttTime birth
= process
->creation_time
;
424 const gchar
*name
= g_quark_to_string(process
->name
);
426 if(processlist_get_process_pixels(process_list
,
429 tfc
->t_context
->index
,
432 &hashed_process_data
) == 1)
434 /* Process not present */
435 processlist_add(process_list
,
438 tfc
->t_context
->index
,
441 &hashed_process_data
);
442 processlist_get_process_pixels(process_list
,
445 tfc
->t_context
->index
,
448 &hashed_process_data
);
449 drawing_insert_square( drawing
, y
, height
);
452 /* Now, the process is in the state hash and our own process hash.
453 * We definitely can draw the items related to the ending state.
456 /* Check if the x position is unset. In can have been left unset by
457 * a draw closure from a after chunk hook. This should never happen,
458 * because it must be set by before chunk hook to the damage_begin
461 g_assert(hashed_process_data
->x
!= -1);
464 DrawContext draw_context
;
466 convert_time_to_pixels(
467 time_window
.start_time
,
473 /* Now create the drawing context that will be used to draw
474 * items related to the last state. */
475 draw_context
.drawable
= drawing
->pixmap
;
476 draw_context
.gc
= drawing
->gc
;
477 draw_context
.pango_layout
= drawing
->pango_layout
;
478 draw_context
.drawinfo
.x_start
= hashed_process_data
->x
;
479 draw_context
.drawinfo
.x_end
= x
;
481 draw_context
.drawinfo
.y_over
= y
;
482 draw_context
.drawinfo
.y_middle
= y
+(height
/4);
483 draw_context
.drawinfo
.y_under
= y
+(height
/2)+2;
485 draw_context
.drawinfo
.x_modify_over
= hashed_process_data
->x
;
486 draw_context
.drawinfo
.x_modify_middle
= hashed_process_data
->x
;
487 draw_context
.drawinfo
.x_modify_under
= hashed_process_data
->x
;
491 PropertiesLine prop_line
= prepare_line(process
);
492 draw_line((void*)&prop_line
, (void*)&draw_context
);
503 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
504 ControlFlowData
*control_flow_data
=
505 (ControlFlowData
*)events_request
->viewer_data
;
506 Tab
*tab
= control_flow_data
->tab
;
508 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
510 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
511 LttvTraceState
*ts
=(LttvTraceState
*)LTTV_TRACEFILE_CONTEXT(tfs
)->t_context
;
516 LttTime evtime
= ltt_event_time(e
);
517 TimeWindow time_window
=
518 lttvwindow_get_time_window(tab
);
520 LttTime end_time
= ltt_time_add(time_window
.start_time
,
521 time_window
.time_width
);
522 //if(time < time_beg || time > time_end) return;
523 if(ltt_time_compare(evtime
, time_window
.start_time
) == -1
524 || ltt_time_compare(evtime
, end_time
) == 1)
527 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e
)),"schedchange") == 0)
529 g_debug("schedchange!");
531 /* Add process to process list (if not present) and get drawing "y" from
532 * process position */
533 guint pid_out
, pid_in
;
534 LttvProcessState
*process_out
, *process_in
;
536 guint y_in
= 0, y_out
= 0, height
= 0, pl_height
= 0;
538 ProcessList
*process_list
=
539 guicontrolflow_get_process_list(control_flow_data
);
542 LttField
*f
= ltt_event_field(e
);
544 element
= ltt_field_member(f
,0);
545 pid_out
= ltt_event_get_long_unsigned(e
,element
);
546 element
= ltt_field_member(f
,1);
547 pid_in
= ltt_event_get_long_unsigned(e
,element
);
548 g_debug("out : %u in : %u", pid_out
, pid_in
);
551 /* Find process pid_out in the list... */
552 process_out
= lttv_state_find_process(tfs
, pid_out
);
553 if(process_out
== NULL
) return 0;
554 g_debug("out : %s",g_quark_to_string(process_out
->state
->s
));
556 birth
= process_out
->creation_time
;
557 const gchar
*name
= g_quark_to_string(process_out
->name
);
558 HashedProcessData
*hashed_process_data_out
= NULL
;
560 if(processlist_get_process_pixels(process_list
,
563 tfc
->t_context
->index
,
566 &hashed_process_data_out
) == 1)
568 /* Process not present */
569 processlist_add(process_list
,
572 tfc
->t_context
->index
,
575 &hashed_process_data_out
);
576 g_assert(processlist_get_process_pixels(process_list
,
579 tfc
->t_context
->index
,
582 &hashed_process_data_out
)==0);
583 drawing_insert_square( control_flow_data
->drawing
, y_out
, height
);
587 /* Find process pid_in in the list... */
588 process_in
= lttv_state_find_process(tfs
, pid_in
);
589 if(process_in
== NULL
) return 0;
590 g_debug("in : %s",g_quark_to_string(process_in
->state
->s
));
592 birth
= process_in
->creation_time
;
593 name
= g_quark_to_string(process_in
->name
);
594 HashedProcessData
*hashed_process_data_in
= NULL
;
596 if(processlist_get_process_pixels(process_list
,
599 tfc
->t_context
->index
,
602 &hashed_process_data_in
) == 1)
604 /* Process not present */
605 processlist_add(process_list
,
608 tfc
->t_context
->index
,
611 &hashed_process_data_in
);
612 processlist_get_process_pixels(process_list
,
615 tfc
->t_context
->index
,
618 &hashed_process_data_in
);
620 drawing_insert_square( control_flow_data
->drawing
, y_in
, height
);
625 /* Find pixels corresponding to time of the event. If the time does
626 * not fit in the window, show a warning, not supposed to happend. */
628 guint width
= control_flow_data
->drawing
->width
;
630 LttTime time
= ltt_event_time(e
);
632 LttTime window_end
= ltt_time_add(time_window
.time_width
,
633 time_window
.start_time
);
636 convert_time_to_pixels(
637 time_window
.start_time
,
642 //assert(x <= width);
644 /* draw what represents the event for outgoing process. */
646 DrawContext
*draw_context_out
= hashed_process_data_out
->draw_context
;
647 draw_context_out
->current
->modify_over
->x
= x
;
648 draw_context_out
->current
->modify_under
->x
= x
;
649 draw_context_out
->current
->modify_over
->y
= y_out
;
650 draw_context_out
->current
->modify_under
->y
= y_out
+(height
/2)+2;
651 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
652 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
653 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
654 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
655 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
656 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
657 //draw_context_out->gc = widget->style->black_gc;
659 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
660 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
662 /* Draw the line/background of the out process */
663 if(draw_context_out
->previous
->middle
->x
== -1)
665 draw_context_out
->previous
->over
->x
=
666 control_flow_data
->drawing
->damage_begin
;
667 draw_context_out
->previous
->middle
->x
=
668 control_flow_data
->drawing
->damage_begin
;
669 draw_context_out
->previous
->under
->x
=
670 control_flow_data
->drawing
->damage_begin
;
672 g_debug("out middle x_beg : %u",control_flow_data
->drawing
->damage_begin
);
675 draw_context_out
->current
->middle
->x
= x
;
676 draw_context_out
->current
->over
->x
= x
;
677 draw_context_out
->current
->under
->x
= x
;
678 draw_context_out
->current
->middle
->y
= y_out
+ height
/2;
679 draw_context_out
->current
->over
->y
= y_out
;
680 draw_context_out
->current
->under
->y
= y_out
+ height
;
681 draw_context_out
->previous
->middle
->y
= y_out
+ height
/2;
682 draw_context_out
->previous
->over
->y
= y_out
;
683 draw_context_out
->previous
->under
->y
= y_out
+ height
;
685 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
686 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
688 if(process_out
->state
->s
== LTTV_STATE_RUN
)
690 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
691 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
692 draw_context_out
->gc
= control_flow_data
->drawing
->gc
;
694 PropertiesBG prop_bg
;
695 prop_bg
.color
= g_new(GdkColor
,1);
699 prop_bg
.color
->red
= 0x1515;
700 prop_bg
.color
->green
= 0x1515;
701 prop_bg
.color
->blue
= 0x8c8c;
704 prop_bg
.color
->red
= 0x4e4e;
705 prop_bg
.color
->green
= 0xa9a9;
706 prop_bg
.color
->blue
= 0xa4a4;
709 prop_bg
.color
->red
= 0x7a7a;
710 prop_bg
.color
->green
= 0x4a4a;
711 prop_bg
.color
->blue
= 0x8b8b;
714 prop_bg
.color
->red
= 0x8080;
715 prop_bg
.color
->green
= 0x7777;
716 prop_bg
.color
->blue
= 0x4747;
719 prop_bg
.color
->red
= 0xe7e7;
720 prop_bg
.color
->green
= 0xe7e7;
721 prop_bg
.color
->blue
= 0xe7e7;
724 g_debug("calling from draw_event");
725 draw_bg((void*)&prop_bg
, (void*)draw_context_out
);
726 g_free(prop_bg
.color
);
727 //gdk_gc_unref(draw_context_out->gc);
730 draw_context_out
->gc
= widget
->style
->black_gc
;
732 GdkColor colorfg_out
= { 0, 0xffff, 0x0000, 0x0000 };
733 GdkColor colorbg_out
= { 0, 0x0000, 0x0000, 0x0000 };
734 PropertiesText prop_text_out
;
735 prop_text_out
.foreground
= &colorfg_out
;
736 prop_text_out
.background
= &colorbg_out
;
737 prop_text_out
.size
= 6;
738 prop_text_out
.position
= OVER
;
740 /* color of text : status of the process */
741 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
743 prop_text_out
.foreground
->red
= 0xffff;
744 prop_text_out
.foreground
->green
= 0xffff;
745 prop_text_out
.foreground
->blue
= 0xffff;
747 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
749 prop_text_out
.foreground
->red
= 0x0fff;
750 prop_text_out
.foreground
->green
= 0xffff;
751 prop_text_out
.foreground
->blue
= 0xfff0;
753 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
755 prop_text_out
.foreground
->red
= 0xffff;
756 prop_text_out
.foreground
->green
= 0xffff;
757 prop_text_out
.foreground
->blue
= 0x0000;
759 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
761 prop_text_out
.foreground
->red
= 0xffff;
762 prop_text_out
.foreground
->green
= 0x0000;
763 prop_text_out
.foreground
->blue
= 0xffff;
765 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
767 prop_text_out
.foreground
->red
= 0xffff;
768 prop_text_out
.foreground
->green
= 0x0000;
769 prop_text_out
.foreground
->blue
= 0x0000;
771 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
773 prop_text_out
.foreground
->red
= 0x0000;
774 prop_text_out
.foreground
->green
= 0xffff;
775 prop_text_out
.foreground
->blue
= 0x0000;
779 prop_text_out
.foreground
->red
= 0xffff;
780 prop_text_out
.foreground
->green
= 0xffff;
781 prop_text_out
.foreground
->blue
= 0xffff;
785 /* Print status of the process : U, WF, WC, E, W, R */
786 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
787 prop_text_out
.text
= "U->";
788 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
789 prop_text_out
.text
= "WF->";
790 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
791 prop_text_out
.text
= "WC->";
792 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
793 prop_text_out
.text
= "E->";
794 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
795 prop_text_out
.text
= "W->";
796 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
797 prop_text_out
.text
= "R->";
799 prop_text_out
.text
= "U";
801 draw_text((void*)&prop_text_out
, (void*)draw_context_out
);
802 //gdk_gc_unref(draw_context_out->gc);
804 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
805 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
806 draw_context_out
->gc
= control_flow_data
->drawing
->gc
;
808 PropertiesLine prop_line_out
;
809 prop_line_out
.color
= g_new(GdkColor
,1);
810 prop_line_out
.line_width
= 2;
811 prop_line_out
.style
= GDK_LINE_SOLID
;
812 prop_line_out
.position
= MIDDLE
;
814 g_debug("out state : %s", g_quark_to_string(process_out
->state
->s
));
816 /* color of line : status of the process */
817 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
819 prop_line_out
.color
->red
= 0xffff;
820 prop_line_out
.color
->green
= 0xffff;
821 prop_line_out
.color
->blue
= 0xffff;
823 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
825 prop_line_out
.color
->red
= 0x0fff;
826 prop_line_out
.color
->green
= 0xffff;
827 prop_line_out
.color
->blue
= 0xfff0;
829 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
831 prop_line_out
.color
->red
= 0xffff;
832 prop_line_out
.color
->green
= 0xffff;
833 prop_line_out
.color
->blue
= 0x0000;
835 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
837 prop_line_out
.color
->red
= 0xffff;
838 prop_line_out
.color
->green
= 0x0000;
839 prop_line_out
.color
->blue
= 0xffff;
841 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
843 prop_line_out
.color
->red
= 0xffff;
844 prop_line_out
.color
->green
= 0x0000;
845 prop_line_out
.color
->blue
= 0x0000;
847 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
849 prop_line_out
.color
->red
= 0x0000;
850 prop_line_out
.color
->green
= 0xffff;
851 prop_line_out
.color
->blue
= 0x0000;
855 prop_line_out
.color
->red
= 0xffff;
856 prop_line_out
.color
->green
= 0xffff;
857 prop_line_out
.color
->blue
= 0xffff;
860 draw_line((void*)&prop_line_out
, (void*)draw_context_out
);
861 g_free(prop_line_out
.color
);
862 //gdk_gc_unref(draw_context_out->gc);
863 /* Note : finishing line will have to be added when trace read over. */
865 /* Finally, update the drawing context of the pid_in. */
867 DrawContext
*draw_context_in
= hashed_process_data_in
->draw_context
;
868 draw_context_in
->current
->modify_over
->x
= x
;
869 draw_context_in
->current
->modify_under
->x
= x
;
870 draw_context_in
->current
->modify_over
->y
= y_in
;
871 draw_context_in
->current
->modify_under
->y
= y_in
+(height
/2)+2;
872 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
873 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
874 widget
= control_flow_data
->drawing
->drawing_area
;
875 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
876 //draw_context_in->gc = widget->style->black_gc;
877 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
878 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
880 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
881 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
883 /* Draw the line/bg of the in process */
884 if(draw_context_in
->previous
->middle
->x
== -1)
886 draw_context_in
->previous
->over
->x
=
887 control_flow_data
->drawing
->damage_begin
;
888 draw_context_in
->previous
->middle
->x
=
889 control_flow_data
->drawing
->damage_begin
;
890 draw_context_in
->previous
->under
->x
=
891 control_flow_data
->drawing
->damage_begin
;
893 g_debug("in middle x_beg : %u",control_flow_data
->drawing
->damage_begin
);
897 draw_context_in
->current
->middle
->x
= x
;
898 draw_context_in
->current
->over
->x
= x
;
899 draw_context_in
->current
->under
->x
= x
;
900 draw_context_in
->current
->middle
->y
= y_in
+ height
/2;
901 draw_context_in
->current
->over
->y
= y_in
;
902 draw_context_in
->current
->under
->y
= y_in
+ height
;
903 draw_context_in
->previous
->middle
->y
= y_in
+ height
/2;
904 draw_context_in
->previous
->over
->y
= y_in
;
905 draw_context_in
->previous
->under
->y
= y_in
+ height
;
907 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
908 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
911 if(process_in
->state
->s
== LTTV_STATE_RUN
)
913 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
914 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
915 draw_context_in
->gc
= control_flow_data
->drawing
->gc
;
917 PropertiesBG prop_bg
;
918 prop_bg
.color
= g_new(GdkColor
,1);
922 prop_bg
.color
->red
= 0x1515;
923 prop_bg
.color
->green
= 0x1515;
924 prop_bg
.color
->blue
= 0x8c8c;
927 prop_bg
.color
->red
= 0x4e4e;
928 prop_bg
.color
->green
= 0xa9a9;
929 prop_bg
.color
->blue
= 0xa4a4;
932 prop_bg
.color
->red
= 0x7a7a;
933 prop_bg
.color
->green
= 0x4a4a;
934 prop_bg
.color
->blue
= 0x8b8b;
937 prop_bg
.color
->red
= 0x8080;
938 prop_bg
.color
->green
= 0x7777;
939 prop_bg
.color
->blue
= 0x4747;
942 prop_bg
.color
->red
= 0xe7e7;
943 prop_bg
.color
->green
= 0xe7e7;
944 prop_bg
.color
->blue
= 0xe7e7;
948 draw_bg((void*)&prop_bg
, (void*)draw_context_in
);
949 g_free(prop_bg
.color
);
950 //gdk_gc_unref(draw_context_in->gc);
953 draw_context_in
->gc
= widget
->style
->black_gc
;
955 GdkColor colorfg_in
= { 0, 0x0000, 0xffff, 0x0000 };
956 GdkColor colorbg_in
= { 0, 0x0000, 0x0000, 0x0000 };
957 PropertiesText prop_text_in
;
958 prop_text_in
.foreground
= &colorfg_in
;
959 prop_text_in
.background
= &colorbg_in
;
960 prop_text_in
.size
= 6;
961 prop_text_in
.position
= OVER
;
963 g_debug("in state : %s", g_quark_to_string(process_in
->state
->s
));
964 /* foreground of text : status of the process */
965 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
967 prop_text_in
.foreground
->red
= 0xffff;
968 prop_text_in
.foreground
->green
= 0xffff;
969 prop_text_in
.foreground
->blue
= 0xffff;
971 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
973 prop_text_in
.foreground
->red
= 0x0fff;
974 prop_text_in
.foreground
->green
= 0xffff;
975 prop_text_in
.foreground
->blue
= 0xfff0;
977 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
979 prop_text_in
.foreground
->red
= 0xffff;
980 prop_text_in
.foreground
->green
= 0xffff;
981 prop_text_in
.foreground
->blue
= 0x0000;
983 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
985 prop_text_in
.foreground
->red
= 0xffff;
986 prop_text_in
.foreground
->green
= 0x0000;
987 prop_text_in
.foreground
->blue
= 0xffff;
989 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
991 prop_text_in
.foreground
->red
= 0xffff;
992 prop_text_in
.foreground
->green
= 0x0000;
993 prop_text_in
.foreground
->blue
= 0x0000;
995 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
997 prop_text_in
.foreground
->red
= 0x0000;
998 prop_text_in
.foreground
->green
= 0xffff;
999 prop_text_in
.foreground
->blue
= 0x0000;
1003 prop_text_in
.foreground
->red
= 0xffff;
1004 prop_text_in
.foreground
->green
= 0xffff;
1005 prop_text_in
.foreground
->blue
= 0xffff;
1010 /* Print status of the process : U, WF, WC, E, W, R */
1011 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
1012 prop_text_in
.text
= "U->";
1013 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
1014 prop_text_in
.text
= "WF->";
1015 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
1016 prop_text_in
.text
= "WC->";
1017 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
1018 prop_text_in
.text
= "E->";
1019 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
1020 prop_text_in
.text
= "W->";
1021 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
1022 prop_text_in
.text
= "R->";
1024 prop_text_in
.text
= "U";
1026 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
1027 //gdk_gc_unref(draw_context_in->gc);
1029 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1030 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
1031 draw_context_in
->gc
= control_flow_data
->drawing
->gc
;
1033 PropertiesLine prop_line_in
;
1034 prop_line_in
.color
= g_new(GdkColor
,1);
1035 prop_line_in
.line_width
= 2;
1036 prop_line_in
.style
= GDK_LINE_SOLID
;
1037 prop_line_in
.position
= MIDDLE
;
1039 /* color of line : status of the process */
1040 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
1042 prop_line_in
.color
->red
= 0xffff;
1043 prop_line_in
.color
->green
= 0xffff;
1044 prop_line_in
.color
->blue
= 0xffff;
1046 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
1048 prop_line_in
.color
->red
= 0x0fff;
1049 prop_line_in
.color
->green
= 0xffff;
1050 prop_line_in
.color
->blue
= 0xfff0;
1052 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
1054 prop_line_in
.color
->red
= 0xffff;
1055 prop_line_in
.color
->green
= 0xffff;
1056 prop_line_in
.color
->blue
= 0x0000;
1058 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
1060 prop_line_in
.color
->red
= 0xffff;
1061 prop_line_in
.color
->green
= 0x0000;
1062 prop_line_in
.color
->blue
= 0xffff;
1064 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
1066 prop_line_in
.color
->red
= 0xffff;
1067 prop_line_in
.color
->green
= 0x0000;
1068 prop_line_in
.color
->blue
= 0x0000;
1070 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
1072 prop_line_in
.color
->red
= 0x0000;
1073 prop_line_in
.color
->green
= 0xffff;
1074 prop_line_in
.color
->blue
= 0x0000;
1078 prop_line_in
.color
->red
= 0xffff;
1079 prop_line_in
.color
->green
= 0xffff;
1080 prop_line_in
.color
->blue
= 0xffff;
1083 draw_line((void*)&prop_line_in
, (void*)draw_context_in
);
1084 g_free(prop_line_in
.color
);
1085 //gdk_gc_unref(draw_context_in->gc);
1095 GString
*string
= g_string_new("");;
1096 gboolean field_names
= TRUE
, state
= TRUE
;
1098 lttv_event_to_string(e
, tfc
->tf
, string
, TRUE
, field_names
, tfs
);
1099 g_string_append_printf(string
,"\n");
1102 g_string_append_printf(string
, " %s",
1103 g_quark_to_string(tfs
->process
->state
->s
));
1106 g_info("%s",string
->str
);
1108 g_string_free(string
, TRUE
);
1110 /* End of text dump */
1117 * The draw after hook is called by the reading API to have a
1118 * particular event drawn on the screen.
1119 * @param hook_data ControlFlowData structure of the viewer.
1120 * @param call_data Event context.
1122 * This function adds items to be drawn in a queue for each process.
1125 int draw_after_hook(void *hook_data
, void *call_data
)
1127 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
1128 ControlFlowData
*control_flow_data
= events_request
->viewer_data
;
1130 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
1132 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
1133 LttvTraceState
*ts
=(LttvTraceState
*)LTTV_TRACEFILE_CONTEXT(tfs
)->t_context
;
1138 LttTime evtime
= ltt_event_time(e
);
1139 TimeWindow time_window
=
1140 lttvwindow_get_time_window(control_flow_data
->tab
);
1142 LttTime end_time
= ltt_time_add(time_window
.start_time
,
1143 time_window
.time_width
);
1145 if(ltt_time_compare(evtime
, time_window
.start_time
) == -1
1146 || ltt_time_compare(evtime
, end_time
) == 1)
1149 guint width
= control_flow_data
->drawing
->width
;
1151 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e
)),"schedchange") == 0) {
1153 g_debug("schedchange!");
1156 /* Add process to process list (if not present) */
1157 LttvProcessState
*process_out
, *process_in
;
1159 guint y_in
= 0, y_out
= 0, height
= 0, pl_height
= 0;
1160 HashedProcessData
*hashed_process_data_in
= NULL
;
1162 ProcessList
*process_list
=
1163 guicontrolflow_get_process_list(control_flow_data
);
1168 LttField
*f
= ltt_event_field(e
);
1170 element
= ltt_field_member(f
,0);
1171 pid_out
= ltt_event_get_long_unsigned(e
,element
);
1172 element
= ltt_field_member(f
,1);
1173 pid_in
= ltt_event_get_long_unsigned(e
,element
);
1174 g_debug("out : %u in : %u", pid_out
, pid_in
);
1178 /* Find process pid_in in the list... */
1179 process_in
= lttv_state_find_process(tfs
, pid_in
);
1180 /* It should exist, because we are after the state update. */
1181 g_assert(process_in
!= NULL
);
1183 birth
= process_in
->creation_time
;
1184 const gchar
*name
= g_quark_to_string(process_in
->name
);
1186 if(processlist_get_process_pixels(process_list
,
1189 tfc
->t_context
->index
,
1192 &hashed_process_data_in
) == 1)
1194 /* Process not present */
1195 processlist_add(process_list
,
1198 tfc
->t_context
->index
,
1201 &hashed_process_data_in
);
1202 processlist_get_process_pixels(process_list
,
1205 tfc
->t_context
->index
,
1208 &hashed_process_data_in
);
1209 drawing_insert_square( control_flow_data
->drawing
, y_in
, height
);
1212 convert_time_to_pixels(
1213 time_window
.start_time
,
1217 &hashed_process_data_in
->x
);
1225 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
1226 ControlFlowData
*control_flow_data
= events_request
->viewer_data
;
1228 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
1230 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
1231 LttvTraceState
*ts
=(LttvTraceState
*)LTTV_TRACEFILE_CONTEXT(tfs
)->t_context
;
1237 LttTime evtime
= ltt_event_time(e
);
1238 TimeWindow time_window
=
1239 lttvwindow_get_time_window(control_flow_data
->tab
);
1241 LttTime end_time
= ltt_time_add(time_window
.start_time
,
1242 time_window
.time_width
);
1243 //if(time < time_beg || time > time_end) return;
1244 if(ltt_time_compare(evtime
, time_window
.start_time
) == -1
1245 || ltt_time_compare(evtime
, end_time
) == 1)
1249 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e
)),"schedchange") == 0)
1251 g_debug("schedchange!");
1253 /* Add process to process list (if not present) and get drawing "y" from
1254 * process position */
1255 guint pid_out
, pid_in
;
1256 LttvProcessState
*process_out
, *process_in
;
1258 guint y_in
= 0, y_out
= 0, height
= 0, pl_height
= 0;
1260 ProcessList
*process_list
=
1261 guicontrolflow_get_process_list(control_flow_data
);
1264 LttField
*f
= ltt_event_field(e
);
1266 element
= ltt_field_member(f
,0);
1267 pid_out
= ltt_event_get_long_unsigned(e
,element
);
1268 element
= ltt_field_member(f
,1);
1269 pid_in
= ltt_event_get_long_unsigned(e
,element
);
1270 //g_debug("out : %u in : %u", pid_out, pid_in);
1273 /* Find process pid_out in the list... */
1274 process_out
= lttv_state_find_process(tfs
, pid_out
);
1275 if(process_out
== NULL
) return 0;
1276 //g_debug("out : %s",g_quark_to_string(process_out->state->s));
1278 birth
= process_out
->creation_time
;
1279 gchar
*name
= strdup(g_quark_to_string(process_out
->name
));
1280 HashedProcessData
*hashed_process_data_out
= NULL
;
1282 if(processlist_get_process_pixels(process_list
,
1285 tfc
->t_context
->index
,
1288 &hashed_process_data_out
) == 1)
1290 /* Process not present */
1291 processlist_add(process_list
,
1294 tfc
->t_context
->index
,
1297 &hashed_process_data_out
);
1298 processlist_get_process_pixels(process_list
,
1301 tfc
->t_context
->index
,
1304 &hashed_process_data_out
);
1305 drawing_insert_square( control_flow_data
->drawing
, y_out
, height
);
1310 /* Find process pid_in in the list... */
1311 process_in
= lttv_state_find_process(tfs
, pid_in
);
1312 if(process_in
== NULL
) return 0;
1313 //g_debug("in : %s",g_quark_to_string(process_in->state->s));
1315 birth
= process_in
->creation_time
;
1316 name
= strdup(g_quark_to_string(process_in
->name
));
1317 HashedProcessData
*hashed_process_data_in
= NULL
;
1319 if(processlist_get_process_pixels(process_list
,
1322 tfc
->t_context
->index
,
1325 &hashed_process_data_in
) == 1)
1327 /* Process not present */
1328 processlist_add(process_list
,
1331 tfc
->t_context
->index
,
1334 &hashed_process_data_in
);
1335 processlist_get_process_pixels(process_list
,
1338 tfc
->t_context
->index
,
1341 &hashed_process_data_in
);
1343 drawing_insert_square( control_flow_data
->drawing
, y_in
, height
);
1348 /* Find pixels corresponding to time of the event. If the time does
1349 * not fit in the window, show a warning, not supposed to happend. */
1351 //guint width = control_flow_data->drawing->drawing_area->allocation.width;
1353 //LttTime time = ltt_event_time(e);
1355 //LttTime window_end = ltt_time_add(time_window->time_width,
1356 // time_window->start_time);
1359 //convert_time_to_pixels(
1360 // time_window->start_time,
1366 //assert(x <= width);
1368 /* draw what represents the event for outgoing process. */
1370 DrawContext
*draw_context_out
= hashed_process_data_out
->draw_context
;
1371 //draw_context_out->current->modify_over->x = x;
1372 draw_context_out
->current
->modify_over
->y
= y_out
;
1373 draw_context_out
->current
->modify_under
->y
= y_out
+(height
/2)+2;
1374 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
1375 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
1376 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
1377 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
1379 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
1380 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
1382 /*if(process_out->state->s == LTTV_STATE_RUN)
1384 draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1385 gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
1386 PropertiesBG prop_bg;
1387 prop_bg.color = g_new(GdkColor,1);
1389 prop_bg.color->red = 0xffff;
1390 prop_bg.color->green = 0xffff;
1391 prop_bg.color->blue = 0xffff;
1393 draw_bg((void*)&prop_bg, (void*)draw_context_out);
1394 g_free(prop_bg.color);
1395 gdk_gc_unref(draw_context_out->gc);
1398 draw_context_out
->gc
= widget
->style
->black_gc
;
1400 GdkColor colorfg_out
= { 0, 0xffff, 0x0000, 0x0000 };
1401 GdkColor colorbg_out
= { 0, 0x0000, 0x0000, 0x0000 };
1402 PropertiesText prop_text_out
;
1403 prop_text_out
.foreground
= &colorfg_out
;
1404 prop_text_out
.background
= &colorbg_out
;
1405 prop_text_out
.size
= 6;
1406 prop_text_out
.position
= OVER
;
1408 /* color of text : status of the process */
1409 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
1411 prop_text_out
.foreground
->red
= 0xffff;
1412 prop_text_out
.foreground
->green
= 0xffff;
1413 prop_text_out
.foreground
->blue
= 0xffff;
1415 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
1417 prop_text_out
.foreground
->red
= 0x0fff;
1418 prop_text_out
.foreground
->green
= 0xffff;
1419 prop_text_out
.foreground
->blue
= 0xfff0;
1421 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
1423 prop_text_out
.foreground
->red
= 0xffff;
1424 prop_text_out
.foreground
->green
= 0xffff;
1425 prop_text_out
.foreground
->blue
= 0x0000;
1427 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
1429 prop_text_out
.foreground
->red
= 0xffff;
1430 prop_text_out
.foreground
->green
= 0x0000;
1431 prop_text_out
.foreground
->blue
= 0xffff;
1433 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
1435 prop_text_out
.foreground
->red
= 0xffff;
1436 prop_text_out
.foreground
->green
= 0x0000;
1437 prop_text_out
.foreground
->blue
= 0x0000;
1439 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
1441 prop_text_out
.foreground
->red
= 0x0000;
1442 prop_text_out
.foreground
->green
= 0xffff;
1443 prop_text_out
.foreground
->blue
= 0x0000;
1447 prop_text_out
.foreground
->red
= 0xffff;
1448 prop_text_out
.foreground
->green
= 0xffff;
1449 prop_text_out
.foreground
->blue
= 0xffff;
1452 /* Print status of the process : U, WF, WC, E, W, R */
1453 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
1454 prop_text_out
.text
= "U";
1455 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
1456 prop_text_out
.text
= "WF";
1457 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
1458 prop_text_out
.text
= "WC";
1459 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
1460 prop_text_out
.text
= "E";
1461 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
1462 prop_text_out
.text
= "W";
1463 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
1464 prop_text_out
.text
= "R";
1466 prop_text_out
.text
= "U";
1468 draw_text((void*)&prop_text_out
, (void*)draw_context_out
);
1470 //gdk_gc_unref(draw_context_out->gc);
1472 draw_context_out
->current
->middle
->y
= y_out
+height
/2;
1473 draw_context_out
->current
->over
->y
= y_out
;
1474 draw_context_out
->current
->under
->y
= y_out
+height
;
1475 draw_context_out
->current
->status
= process_out
->state
->s
;
1477 /* for pid_out : remove previous, Prev = current, new current (default) */
1478 g_free(draw_context_out
->previous
->modify_under
);
1479 g_free(draw_context_out
->previous
->modify_middle
);
1480 g_free(draw_context_out
->previous
->modify_over
);
1481 g_free(draw_context_out
->previous
->under
);
1482 g_free(draw_context_out
->previous
->middle
);
1483 g_free(draw_context_out
->previous
->over
);
1484 g_free(draw_context_out
->previous
);
1486 draw_context_out
->previous
= draw_context_out
->current
;
1488 draw_context_out
->current
= g_new(DrawInfo
,1);
1489 draw_context_out
->current
->over
= g_new(ItemInfo
,1);
1490 draw_context_out
->current
->over
->x
= -1;
1491 draw_context_out
->current
->over
->y
= -1;
1492 draw_context_out
->current
->middle
= g_new(ItemInfo
,1);
1493 draw_context_out
->current
->middle
->x
= -1;
1494 draw_context_out
->current
->middle
->y
= -1;
1495 draw_context_out
->current
->under
= g_new(ItemInfo
,1);
1496 draw_context_out
->current
->under
->x
= -1;
1497 draw_context_out
->current
->under
->y
= -1;
1498 draw_context_out
->current
->modify_over
= g_new(ItemInfo
,1);
1499 draw_context_out
->current
->modify_over
->x
= -1;
1500 draw_context_out
->current
->modify_over
->y
= -1;
1501 draw_context_out
->current
->modify_middle
= g_new(ItemInfo
,1);
1502 draw_context_out
->current
->modify_middle
->x
= -1;
1503 draw_context_out
->current
->modify_middle
->y
= -1;
1504 draw_context_out
->current
->modify_under
= g_new(ItemInfo
,1);
1505 draw_context_out
->current
->modify_under
->x
= -1;
1506 draw_context_out
->current
->modify_under
->y
= -1;
1507 draw_context_out
->current
->status
= LTTV_STATE_UNNAMED
;
1509 /* Finally, update the drawing context of the pid_in. */
1511 DrawContext
*draw_context_in
= hashed_process_data_in
->draw_context
;
1512 //draw_context_in->current->modify_over->x = x;
1513 draw_context_in
->current
->modify_over
->y
= y_in
;
1514 draw_context_in
->current
->modify_under
->y
= y_in
+(height
/2)+2;
1515 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
1516 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
1517 widget
= control_flow_data
->drawing
->drawing_area
;
1518 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
1520 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
1521 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
1523 /*if(process_in->state->s == LTTV_STATE_RUN)
1525 draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1526 gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
1527 PropertiesBG prop_bg;
1528 prop_bg.color = g_new(GdkColor,1);
1530 prop_bg.color->red = 0xffff;
1531 prop_bg.color->green = 0xffff;
1532 prop_bg.color->blue = 0xffff;
1534 draw_bg((void*)&prop_bg, (void*)draw_context_in);
1535 g_free(prop_bg.color);
1536 gdk_gc_unref(draw_context_in->gc);
1539 draw_context_in
->gc
= widget
->style
->black_gc
;
1541 GdkColor colorfg_in
= { 0, 0x0000, 0xffff, 0x0000 };
1542 GdkColor colorbg_in
= { 0, 0x0000, 0x0000, 0x0000 };
1543 PropertiesText prop_text_in
;
1544 prop_text_in
.foreground
= &colorfg_in
;
1545 prop_text_in
.background
= &colorbg_in
;
1546 prop_text_in
.size
= 6;
1547 prop_text_in
.position
= OVER
;
1549 /* foreground of text : status of the process */
1550 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
1552 prop_text_in
.foreground
->red
= 0xffff;
1553 prop_text_in
.foreground
->green
= 0xffff;
1554 prop_text_in
.foreground
->blue
= 0xffff;
1556 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
1558 prop_text_in
.foreground
->red
= 0x0fff;
1559 prop_text_in
.foreground
->green
= 0xffff;
1560 prop_text_in
.foreground
->blue
= 0xfff0;
1562 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
1564 prop_text_in
.foreground
->red
= 0xffff;
1565 prop_text_in
.foreground
->green
= 0xffff;
1566 prop_text_in
.foreground
->blue
= 0x0000;
1568 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
1570 prop_text_in
.foreground
->red
= 0xffff;
1571 prop_text_in
.foreground
->green
= 0x0000;
1572 prop_text_in
.foreground
->blue
= 0xffff;
1574 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
1576 prop_text_in
.foreground
->red
= 0xffff;
1577 prop_text_in
.foreground
->green
= 0x0000;
1578 prop_text_in
.foreground
->blue
= 0x0000;
1580 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
1582 prop_text_in
.foreground
->red
= 0x0000;
1583 prop_text_in
.foreground
->green
= 0xffff;
1584 prop_text_in
.foreground
->blue
= 0x0000;
1588 prop_text_in
.foreground
->red
= 0xffff;
1589 prop_text_in
.foreground
->green
= 0xffff;
1590 prop_text_in
.foreground
->blue
= 0xffff;
1594 /* Print status of the process : U, WF, WC, E, W, R */
1595 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
1596 prop_text_in
.text
= "U";
1597 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
1598 prop_text_in
.text
= "WF";
1599 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
1600 prop_text_in
.text
= "WC";
1601 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
1602 prop_text_in
.text
= "E";
1603 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
1604 prop_text_in
.text
= "W";
1605 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
1606 prop_text_in
.text
= "R";
1608 prop_text_in
.text
= "U";
1610 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
1613 if(process_in
->state
->s
== LTTV_STATE_RUN
)
1616 prop_text_in
.foreground
= &colorfg_in
;
1617 prop_text_in
.background
= &colorbg_in
;
1618 prop_text_in
.foreground
->red
= 0xffff;
1619 prop_text_in
.foreground
->green
= 0xffff;
1620 prop_text_in
.foreground
->blue
= 0xffff;
1621 prop_text_in
.size
= 6;
1622 prop_text_in
.position
= UNDER
;
1624 prop_text_in
.text
= g_new(gchar
, 260);
1625 strcpy(prop_text_in
.text
, "CPU ");
1626 snprintf(tmp
, 255, "%u", tfc
->index
);
1627 strcat(prop_text_in
.text
, tmp
);
1629 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
1630 g_free(prop_text_in
.text
);
1634 draw_context_in
->current
->middle
->y
= y_in
+height
/2;
1635 draw_context_in
->current
->over
->y
= y_in
;
1636 draw_context_in
->current
->under
->y
= y_in
+height
;
1637 draw_context_in
->current
->status
= process_in
->state
->s
;
1639 /* for pid_in : remove previous, Prev = current, new current (default) */
1640 g_free(draw_context_in
->previous
->modify_under
);
1641 g_free(draw_context_in
->previous
->modify_middle
);
1642 g_free(draw_context_in
->previous
->modify_over
);
1643 g_free(draw_context_in
->previous
->under
);
1644 g_free(draw_context_in
->previous
->middle
);
1645 g_free(draw_context_in
->previous
->over
);
1646 g_free(draw_context_in
->previous
);
1648 draw_context_in
->previous
= draw_context_in
->current
;
1650 draw_context_in
->current
= g_new(DrawInfo
,1);
1651 draw_context_in
->current
->over
= g_new(ItemInfo
,1);
1652 draw_context_in
->current
->over
->x
= -1;
1653 draw_context_in
->current
->over
->y
= -1;
1654 draw_context_in
->current
->middle
= g_new(ItemInfo
,1);
1655 draw_context_in
->current
->middle
->x
= -1;
1656 draw_context_in
->current
->middle
->y
= -1;
1657 draw_context_in
->current
->under
= g_new(ItemInfo
,1);
1658 draw_context_in
->current
->under
->x
= -1;
1659 draw_context_in
->current
->under
->y
= -1;
1660 draw_context_in
->current
->modify_over
= g_new(ItemInfo
,1);
1661 draw_context_in
->current
->modify_over
->x
= -1;
1662 draw_context_in
->current
->modify_over
->y
= -1;
1663 draw_context_in
->current
->modify_middle
= g_new(ItemInfo
,1);
1664 draw_context_in
->current
->modify_middle
->x
= -1;
1665 draw_context_in
->current
->modify_middle
->y
= -1;
1666 draw_context_in
->current
->modify_under
= g_new(ItemInfo
,1);
1667 draw_context_in
->current
->modify_under
->x
= -1;
1668 draw_context_in
->current
->modify_under
->y
= -1;
1669 draw_context_in
->current
->status
= LTTV_STATE_UNNAMED
;
1680 gint
update_time_window_hook(void *hook_data
, void *call_data
)
1682 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1683 Drawing_t
*drawing
= control_flow_data
->drawing
;
1685 const TimeWindowNotifyData
*time_window_nofify_data
=
1686 ((const TimeWindowNotifyData
*)call_data
);
1688 TimeWindow
*old_time_window
=
1689 time_window_nofify_data
->old_time_window
;
1690 TimeWindow
*new_time_window
=
1691 time_window_nofify_data
->new_time_window
;
1693 /* Update the ruler */
1694 drawing_update_ruler(control_flow_data
->drawing
,
1698 /* Two cases : zoom in/out or scrolling */
1700 /* In order to make sure we can reuse the old drawing, the scale must
1701 * be the same and the new time interval being partly located in the
1702 * currently shown time interval. (reuse is only for scrolling)
1705 g_info("Old time window HOOK : %u, %u to %u, %u",
1706 old_time_window
->start_time
.tv_sec
,
1707 old_time_window
->start_time
.tv_nsec
,
1708 old_time_window
->time_width
.tv_sec
,
1709 old_time_window
->time_width
.tv_nsec
);
1711 g_info("New time window HOOK : %u, %u to %u, %u",
1712 new_time_window
->start_time
.tv_sec
,
1713 new_time_window
->start_time
.tv_nsec
,
1714 new_time_window
->time_width
.tv_sec
,
1715 new_time_window
->time_width
.tv_nsec
);
1717 if( new_time_window
->time_width
.tv_sec
== old_time_window
->time_width
.tv_sec
1718 && new_time_window
->time_width
.tv_nsec
== old_time_window
->time_width
.tv_nsec
)
1720 /* Same scale (scrolling) */
1721 g_info("scrolling");
1722 LttTime
*ns
= &new_time_window
->start_time
;
1723 LttTime
*os
= &old_time_window
->start_time
;
1724 LttTime old_end
= ltt_time_add(old_time_window
->start_time
,
1725 old_time_window
->time_width
);
1726 LttTime new_end
= ltt_time_add(new_time_window
->start_time
,
1727 new_time_window
->time_width
);
1729 //if(ns<os+w && os+w<ns+w)
1730 //if(ns<old_end && os<ns)
1731 if(ltt_time_compare(*ns
, old_end
) == -1
1732 && ltt_time_compare(*os
, *ns
) == -1)
1734 g_info("scrolling near right");
1735 /* Scroll right, keep right part of the screen */
1737 guint width
= control_flow_data
->drawing
->width
;
1738 convert_time_to_pixels(
1745 /* Copy old data to new location */
1746 gdk_draw_drawable (control_flow_data
->drawing
->pixmap
,
1747 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1748 control_flow_data
->drawing
->pixmap
,
1751 control_flow_data
->drawing
->width
-x
+SAFETY
, -1);
1753 if(drawing
->damage_begin
== drawing
->damage_end
)
1754 drawing
->damage_begin
= control_flow_data
->drawing
->width
-x
;
1756 drawing
->damage_begin
= 0;
1758 drawing
->damage_end
= control_flow_data
->drawing
->width
;
1760 /* Clear the data request background, but not SAFETY */
1761 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1762 //control_flow_data->drawing->drawing_area->style->black_gc,
1763 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1765 drawing
->damage_begin
+SAFETY
, 0,
1766 drawing
->damage_end
- drawing
->damage_begin
, // do not overlap
1767 control_flow_data
->drawing
->height
);
1769 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1771 control_flow_data
->drawing
->width
,
1772 control_flow_data
->drawing
->height
);
1774 /* Get new data for the rest. */
1775 drawing_data_request(control_flow_data
->drawing
,
1776 &control_flow_data
->drawing
->pixmap
,
1777 drawing
->damage_begin
, 0,
1778 drawing
->damage_end
- drawing
->damage_begin
,
1779 control_flow_data
->drawing
->height
);
1782 //if(ns<os && os<ns+w)
1783 //if(ns<os && os<new_end)
1784 if(ltt_time_compare(*ns
,*os
) == -1
1785 && ltt_time_compare(*os
,new_end
) == -1)
1787 g_info("scrolling near left");
1788 /* Scroll left, keep left part of the screen */
1790 guint width
= control_flow_data
->drawing
->width
;
1791 convert_time_to_pixels(
1799 /* Copy old data to new location */
1800 gdk_draw_drawable (control_flow_data
->drawing
->pixmap
,
1801 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1802 control_flow_data
->drawing
->pixmap
,
1807 if(drawing
->damage_begin
== drawing
->damage_end
)
1808 drawing
->damage_end
= x
;
1810 drawing
->damage_end
=
1811 control_flow_data
->drawing
->width
;
1813 drawing
->damage_begin
= 0;
1815 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1816 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1818 drawing
->damage_begin
, 0,
1819 drawing
->damage_end
- drawing
->damage_begin
, // do not overlap
1820 control_flow_data
->drawing
->height
);
1822 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1824 control_flow_data
->drawing
->width
,
1825 control_flow_data
->drawing
->height
);
1828 /* Get new data for the rest. */
1829 drawing_data_request(control_flow_data
->drawing
,
1830 &control_flow_data
->drawing
->pixmap
,
1831 drawing
->damage_begin
, 0,
1832 drawing
->damage_end
- drawing
->damage_begin
,
1833 control_flow_data
->drawing
->height
);
1836 if(ltt_time_compare(*ns
,*os
) == 0)
1838 g_info("not scrolling");
1840 g_info("scrolling far");
1841 /* Cannot reuse any part of the screen : far jump */
1844 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1845 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1848 control_flow_data
->drawing
->width
+SAFETY
, // do not overlap
1849 control_flow_data
->drawing
->height
);
1851 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1853 control_flow_data
->drawing
->width
,
1854 control_flow_data
->drawing
->height
);
1856 drawing
->damage_begin
= 0;
1857 drawing
->damage_end
= control_flow_data
->drawing
->width
;
1859 drawing_data_request(control_flow_data
->drawing
,
1860 &control_flow_data
->drawing
->pixmap
,
1862 control_flow_data
->drawing
->width
,
1863 control_flow_data
->drawing
->height
);
1869 /* Different scale (zoom) */
1872 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1873 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1876 control_flow_data
->drawing
->width
+SAFETY
, // do not overlap
1877 control_flow_data
->drawing
->height
);
1879 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1881 control_flow_data
->drawing
->width
,
1882 control_flow_data
->drawing
->height
);
1884 drawing
->damage_begin
= 0;
1885 drawing
->damage_end
= control_flow_data
->drawing
->width
;
1887 drawing_data_request(control_flow_data
->drawing
,
1888 &control_flow_data
->drawing
->pixmap
,
1890 control_flow_data
->drawing
->width
,
1891 control_flow_data
->drawing
->height
);
1899 gint
traceset_notify(void *hook_data
, void *call_data
)
1901 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1902 Drawing_t
*drawing
= control_flow_data
->drawing
;
1903 GtkWidget
*widget
= drawing
->drawing_area
;
1905 drawing
->damage_begin
= 0;
1906 drawing
->damage_end
= drawing
->width
;
1908 drawing_clear(control_flow_data
->drawing
);
1909 processlist_clear(control_flow_data
->process_list
);
1911 if(drawing
->damage_begin
< drawing
->damage_end
)
1913 drawing_data_request(drawing
,
1915 drawing
->damage_begin
,
1917 drawing
->damage_end
-drawing
->damage_begin
,
1921 gtk_widget_queue_draw_area(drawing
->drawing_area
,
1926 request_background_data(control_flow_data
);
1931 gint
redraw_notify(void *hook_data
, void *call_data
)
1933 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1934 Drawing_t
*drawing
= control_flow_data
->drawing
;
1935 GtkWidget
*widget
= drawing
->drawing_area
;
1937 drawing
->damage_begin
= 0;
1938 drawing
->damage_end
= drawing
->width
;
1942 gdk_draw_rectangle (drawing
->pixmap
,
1943 widget
->style
->black_gc
,
1946 drawing
->width
+SAFETY
,
1950 if(drawing
->damage_begin
< drawing
->damage_end
)
1952 drawing_data_request(drawing
,
1954 drawing
->damage_begin
,
1956 drawing
->damage_end
-drawing
->damage_begin
,
1960 gtk_widget_queue_draw_area(drawing
->drawing_area
,
1970 gint
continue_notify(void *hook_data
, void *call_data
)
1972 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1973 Drawing_t
*drawing
= control_flow_data
->drawing
;
1974 GtkWidget
*widget
= drawing
->drawing_area
;
1976 //g_assert(widget->allocation.width == drawing->damage_end);
1978 if(drawing
->damage_begin
< drawing
->damage_end
)
1980 drawing_data_request(drawing
,
1982 drawing
->damage_begin
,
1984 drawing
->damage_end
-drawing
->damage_begin
,
1992 gint
update_current_time_hook(void *hook_data
, void *call_data
)
1994 ControlFlowData
*control_flow_data
= (ControlFlowData
*)hook_data
;
1995 Drawing_t
*drawing
= control_flow_data
->drawing
;
1997 LttTime current_time
= *((LttTime
*)call_data
);
1999 TimeWindow time_window
=
2000 lttvwindow_get_time_window(control_flow_data
->tab
);
2002 LttTime time_begin
= time_window
.start_time
;
2003 LttTime width
= time_window
.time_width
;
2004 LttTime half_width
= ltt_time_div(width
,2.0);
2005 LttTime time_end
= ltt_time_add(time_begin
, width
);
2007 LttvTracesetContext
* tsc
=
2008 lttvwindow_get_traceset_context(control_flow_data
->tab
);
2010 LttTime trace_start
= tsc
->time_span
.start_time
;
2011 LttTime trace_end
= tsc
->time_span
.end_time
;
2013 g_info("New current time HOOK : %u, %u", current_time
.tv_sec
,
2014 current_time
.tv_nsec
);
2018 /* If current time is inside time interval, just move the highlight
2021 /* Else, we have to change the time interval. We have to tell it
2022 * to the main window. */
2023 /* The time interval change will take care of placing the current
2024 * time at the center of the visible area, or nearest possible if we are
2025 * at one end of the trace. */
2028 if(ltt_time_compare(current_time
, time_begin
) == -1)
2030 TimeWindow new_time_window
;
2032 if(ltt_time_compare(current_time
,
2033 ltt_time_add(trace_start
,half_width
)) == -1)
2034 time_begin
= trace_start
;
2036 time_begin
= ltt_time_sub(current_time
,half_width
);
2038 new_time_window
.start_time
= time_begin
;
2039 new_time_window
.time_width
= width
;
2041 lttvwindow_report_time_window(control_flow_data
->tab
, &new_time_window
);
2043 else if(ltt_time_compare(current_time
, time_end
) == 1)
2045 TimeWindow new_time_window
;
2047 if(ltt_time_compare(current_time
, ltt_time_sub(trace_end
, half_width
)) == 1)
2048 time_begin
= ltt_time_sub(trace_end
,width
);
2050 time_begin
= ltt_time_sub(current_time
,half_width
);
2052 new_time_window
.start_time
= time_begin
;
2053 new_time_window
.time_width
= width
;
2055 lttvwindow_report_time_window(control_flow_data
->tab
, &new_time_window
);
2058 //gtk_widget_queue_draw(control_flow_data->drawing->drawing_area);
2059 gtk_widget_queue_draw_area(drawing
->drawing_area
,
2067 typedef struct _ClosureData
{
2068 EventsRequest
*events_request
;
2069 LttvTracesetState
*tss
;
2074 void draw_closure(gpointer key
, gpointer value
, gpointer user_data
)
2081 ProcessInfo
*process_info
= (ProcessInfo
*)key
;
2082 HashedProcessData
*hashed_process_data
= (HashedProcessData
*)value
;
2083 ClosureData
*closure_data
= (ClosureData
*)user_data
;
2085 ControlFlowData
*control_flow_data
=
2086 closure_data
->events_request
->viewer_data
;
2088 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
2090 /* Get y position of process */
2093 processlist_get_pixels_from_data( control_flow_data
->process_list
,
2095 hashed_process_data
,
2098 /* Get last state of process */
2099 LttvTraceContext
*tc
=
2100 ((LttvTracesetContext
*)closure_data
->tss
)->traces
[process_info
->trace_num
];
2101 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)closure_data
->tss
;
2103 LttvTraceState
*ts
= (LttvTraceState
*)tc
;
2104 LttvProcessState
*process
;
2106 /* We do not provide a cpu_name argument assuming that this is not the
2107 idle job (pid 0) and thus its pid is unique across all cpus */
2108 process
= lttv_state_find_process_from_trace(ts
, 0, process_info
->pid
);
2110 /* Draw the closing line */
2111 DrawContext
*draw_context
= hashed_process_data
->draw_context
;
2112 if(draw_context
->previous
->middle
->x
== -1)
2114 draw_context
->previous
->over
->x
=
2115 control_flow_data
->drawing
->damage_begin
;
2116 draw_context
->previous
->middle
->x
=
2117 control_flow_data
->drawing
->damage_begin
;
2118 draw_context
->previous
->under
->x
=
2119 control_flow_data
->drawing
->damage_begin
;
2121 g_debug("out middle x_beg : %u",control_flow_data
->drawing
->damage_begin
);
2124 /* Find pixels corresponding to current time . If the time does
2125 * not fit in the window, show a warning, not supposed to happend. */
2127 guint width
= control_flow_data
->drawing
->width
;
2129 TimeWindow time_window
=
2130 lttvwindow_get_time_window(control_flow_data
->tab
);
2132 LttTime time
= lttv_traceset_context_get_current_tfc(tsc
)->timestamp
;
2134 LttTime window_end
= ltt_time_add(time_window
.time_width
,
2135 time_window
.start_time
);
2137 convert_time_to_pixels(
2138 time_window
.start_time
,
2144 draw_context
->current
->middle
->x
= x
;
2145 draw_context
->current
->over
->x
= x
;
2146 draw_context
->current
->under
->x
= x
;
2147 draw_context
->current
->middle
->y
= y
+ height
/2;
2148 draw_context
->current
->over
->y
= y
;
2149 draw_context
->current
->under
->y
= y
+ height
;
2150 draw_context
->previous
->middle
->y
= y
+ height
/2;
2151 draw_context
->previous
->over
->y
= y
;
2152 draw_context
->previous
->under
->y
= y
+ height
;
2153 draw_context
->drawable
= control_flow_data
->drawing
->pixmap
;
2154 draw_context
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
2155 //draw_context->gc = widget->style->black_gc;
2156 //draw_context->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
2157 //gdk_gc_copy(draw_context->gc, widget->style->black_gc);
2158 draw_context
->gc
= control_flow_data
->drawing
->gc
;
2160 if(process
!= NULL
&& process
->state
->s
== LTTV_STATE_RUN
)
2162 PropertiesBG prop_bg
;
2163 prop_bg
.color
= g_new(GdkColor
,1);
2165 /*switch(tfc->index) {
2167 prop_bg.color->red = 0x1515;
2168 prop_bg.color->green = 0x1515;
2169 prop_bg.color->blue = 0x8c8c;
2172 prop_bg.color->red = 0x4e4e;
2173 prop_bg.color->green = 0xa9a9;
2174 prop_bg.color->blue = 0xa4a4;
2177 prop_bg.color->red = 0x7a7a;
2178 prop_bg.color->green = 0x4a4a;
2179 prop_bg.color->blue = 0x8b8b;
2182 prop_bg.color->red = 0x8080;
2183 prop_bg.color->green = 0x7777;
2184 prop_bg.color->blue = 0x4747;
2187 prop_bg.color->red = 0xe7e7;
2188 prop_bg.color->green = 0xe7e7;
2189 prop_bg.color->blue = 0xe7e7;
2193 g_debug("calling from closure");
2194 //FIXME : I need the cpu number in process's state to draw this.
2195 //draw_bg((void*)&prop_bg, (void*)draw_context);
2196 g_free(prop_bg
.color
);
2200 PropertiesLine prop_line
;
2201 prop_line
.color
= g_new(GdkColor
,1);
2202 prop_line
.line_width
= 2;
2203 prop_line
.style
= GDK_LINE_SOLID
;
2204 prop_line
.position
= MIDDLE
;
2206 /* color of line : status of the process */
2209 if(process
->state
->s
== LTTV_STATE_UNNAMED
)
2211 prop_line
.color
->red
= 0xffff;
2212 prop_line
.color
->green
= 0xffff;
2213 prop_line
.color
->blue
= 0xffff;
2215 else if(process
->state
->s
== LTTV_STATE_WAIT_FORK
)
2217 prop_line
.color
->red
= 0x0fff;
2218 prop_line
.color
->green
= 0xffff;
2219 prop_line
.color
->blue
= 0xfff0;
2221 else if(process
->state
->s
== LTTV_STATE_WAIT_CPU
)
2223 prop_line
.color
->red
= 0xffff;
2224 prop_line
.color
->green
= 0xffff;
2225 prop_line
.color
->blue
= 0x0000;
2227 else if(process
->state
->s
== LTTV_STATE_EXIT
)
2229 prop_line
.color
->red
= 0xffff;
2230 prop_line
.color
->green
= 0x0000;
2231 prop_line
.color
->blue
= 0xffff;
2233 else if(process
->state
->s
== LTTV_STATE_WAIT
)
2235 prop_line
.color
->red
= 0xffff;
2236 prop_line
.color
->green
= 0x0000;
2237 prop_line
.color
->blue
= 0x0000;
2239 else if(process
->state
->s
== LTTV_STATE_RUN
)
2241 prop_line
.color
->red
= 0x0000;
2242 prop_line
.color
->green
= 0xffff;
2243 prop_line
.color
->blue
= 0x0000;
2247 prop_line
.color
->red
= 0xffff;
2248 prop_line
.color
->green
= 0xffff;
2249 prop_line
.color
->blue
= 0xffff;
2255 prop_line
.color
->red
= 0xffff;
2256 prop_line
.color
->green
= 0xffff;
2257 prop_line
.color
->blue
= 0xffff;
2260 draw_line((void*)&prop_line
, (void*)draw_context
);
2261 g_free(prop_line
.color
);
2262 //gdk_gc_unref(draw_context->gc);
2264 /* Reset draw_context of the process for next request */
2266 hashed_process_data
->draw_context
->drawable
= NULL
;
2267 hashed_process_data
->draw_context
->gc
= NULL
;
2268 hashed_process_data
->draw_context
->pango_layout
= NULL
;
2269 hashed_process_data
->draw_context
->current
->over
->x
= -1;
2270 hashed_process_data
->draw_context
->current
->over
->y
= -1;
2271 hashed_process_data
->draw_context
->current
->middle
->x
= -1;
2272 hashed_process_data
->draw_context
->current
->middle
->y
= -1;
2273 hashed_process_data
->draw_context
->current
->under
->x
= -1;
2274 hashed_process_data
->draw_context
->current
->under
->y
= -1;
2275 hashed_process_data
->draw_context
->current
->modify_over
->x
= -1;
2276 hashed_process_data
->draw_context
->current
->modify_over
->y
= -1;
2277 hashed_process_data
->draw_context
->current
->modify_middle
->x
= -1;
2278 hashed_process_data
->draw_context
->current
->modify_middle
->y
= -1;
2279 hashed_process_data
->draw_context
->current
->modify_under
->x
= -1;
2280 hashed_process_data
->draw_context
->current
->modify_under
->y
= -1;
2281 hashed_process_data
->draw_context
->current
->status
= LTTV_STATE_UNNAMED
;
2282 hashed_process_data
->draw_context
->previous
->over
->x
= -1;
2283 hashed_process_data
->draw_context
->previous
->over
->y
= -1;
2284 hashed_process_data
->draw_context
->previous
->middle
->x
= -1;
2285 hashed_process_data
->draw_context
->previous
->middle
->y
= -1;
2286 hashed_process_data
->draw_context
->previous
->under
->x
= -1;
2287 hashed_process_data
->draw_context
->previous
->under
->y
= -1;
2288 hashed_process_data
->draw_context
->previous
->modify_over
->x
= -1;
2289 hashed_process_data
->draw_context
->previous
->modify_over
->y
= -1;
2290 hashed_process_data
->draw_context
->previous
->modify_middle
->x
= -1;
2291 hashed_process_data
->draw_context
->previous
->modify_middle
->y
= -1;
2292 hashed_process_data
->draw_context
->previous
->modify_under
->x
= -1;
2293 hashed_process_data
->draw_context
->previous
->modify_under
->y
= -1;
2294 hashed_process_data
->draw_context
->previous
->status
= LTTV_STATE_UNNAMED
;
2299 int before_chunk(void *hook_data
, void *call_data
)
2301 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
2302 LttvTracesetState
*tss
= LTTV_TRACESET_STATE(call_data
);
2304 drawing_chunk_begin(events_request
, tss
);
2309 int before_request(void *hook_data
, void *call_data
)
2311 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
2312 LttvTracesetState
*tss
= LTTV_TRACESET_STATE(call_data
);
2314 drawing_data_request_begin(events_request
, tss
);
2321 * after request is necessary in addition of after chunk in order to draw
2322 * lines until the end of the screen. after chunk just draws lines until
2329 int after_request(void *hook_data
, void *call_data
)
2331 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
2332 ControlFlowData
*control_flow_data
= events_request
->viewer_data
;
2333 LttvTracesetState
*tss
= LTTV_TRACESET_STATE(call_data
);
2334 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(call_data
);
2336 ProcessList
*process_list
=
2337 guicontrolflow_get_process_list(control_flow_data
);
2338 LttTime end_time
= events_request
->end_time
;
2340 ClosureData closure_data
;
2341 closure_data
.events_request
= (EventsRequest
*)hook_data
;
2342 closure_data
.tss
= tss
;
2343 closure_data
.end_time
= end_time
;
2345 /* Draw last items */
2346 g_hash_table_foreach(process_list
->process_hash
, draw_closure
,
2347 (void*)&closure_data
);
2349 /* Request expose */
2350 drawing_request_expose(events_request
, tss
, end_time
);
2359 int after_chunk(void *hook_data
, void *call_data
)
2361 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
2362 ControlFlowData
*control_flow_data
= events_request
->viewer_data
;
2363 LttvTracesetState
*tss
= LTTV_TRACESET_STATE(call_data
);
2364 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(call_data
);
2365 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
2368 ProcessList
*process_list
=
2369 guicontrolflow_get_process_list(control_flow_data
);
2372 && ltt_time_compare(tfc
->timestamp
, events_request
->end_time
) <= 0)
2373 end_time
= tfc
->timestamp
;
2374 else /* end of traceset, or position now out of request : end */
2375 end_time
= events_request
->end_time
;
2377 ClosureData closure_data
;
2378 closure_data
.events_request
= (EventsRequest
*)hook_data
;
2379 closure_data
.tss
= tss
;
2380 closure_data
.end_time
= end_time
;
2382 /* Draw last items */
2383 g_hash_table_foreach(process_list
->process_hash
, draw_closure
,
2384 (void*)&closure_data
);
2386 /* Request expose */
2387 drawing_request_expose(events_request
, tss
, end_time
);